Xata SDK for TypeScript and JavaScript

The Xata SDK supports TypeScript definitions for your Xata database schema. It also works with JavaScript.

It has zero dependencies and can run in Node.js, V8, Deno, and Bun.

We recommend installing the Xata CLI globally and importing the Xata Client from the code generated by the CLI.

When initializing the Xata CLI with the command xata init in a project, the @xata.io/client package is installed locally using the current project's package manager. In the event a package manager can't be determined, the Xata CLI will prompt you to manually install the @xata.io/client package.

There are three ways to use the SDK:

  1. Schema-generated Client: SDK to create/read/update/delete records in a given database following a schema file (with type-safety).
  2. Schema-less Client: SDK to create/read/update/delete records in any database without schema validation (with partial type-safety).
  3. API Client: SDK to interact with the whole Xata API and all its endpoints.

The TypeScript SDK provides helper methods for creating types based off of Xata client-generated types. The following are exported on the @xata.io/client package:

  • SelectableColumn provides a type with the valid columns for a record.
  • SelectedPick returns a subtype of the record with the requested fields.
  • EditableData removes built-in record methods and reserved fields.

In the example below we create the type myUser with a selection of fields from the client-generated UserRecord:

import { getXataClient } from './xata';
import { SelectedPick, SelectableColumn, EditableData } from '@xata.io/client';
import { UserRecord } from './xata';
 
const xata = getXataClient();
 
const fields: SelectableColumn<UserRecord>[] = ['id', 'name', 'address'];
 
type myUser = EditableData<SelectedPick<UserRecord, typeof fields>>;

Systems such as Next.js expect the server to send serialized data-structures to the client. Since the Xata SDK returns records as objects as well as strings, there's a need to serialize content for client-side use. Serialization transforms the data into a structured text format that can be easily sent and rebuilt on the client side.

Xata provides the .toSerializable() method within the record objects to help with serialization. To revert serialized data back to its original types on the client side, you can use the JSONData helper from @xata.io/client.

An example of a common pattern for this flow in a Next.js system:

/app/page.tsx
import { getXataClient } from './xata';
 
const xata = getXataClient();
 
export default async function Page({ params }: { params: { slug: string } }) {
  // Pull records from the "users" table
  const records = await xata.db.users.getMany();
 
  // Serialize that content, turning any objects into strings
  const serializedRecords = records.toSerializable();
 
  // Pass the serialized content to the client component
  return <MyComponent records={serializedRecords} />;
}

The MyComponent client component can then use JSONData from the client to match against Xata's auto-generated types as shown below.

/components/MyComponent.tsx
'use client';
import { FC } from 'react';
import { JSONData } from '@xata.io/client';
import { UserRecord } from './xata';
 
interface MyComponentProps {
  // The data we serialized still matches the UserRecord shape
  records: JSONData<UserRecord>;
}
 
export const MyComponent: FC<MyComponentProps> = ({ records }) => {
  return (
    <>
      {records.map((record) => {
        // Date objects were converted to strings during serialization.
        // We can always revert them to their original form here in the client, as needed
        const date = new Date(record.createdAt);
        const dateFormatted = date.toLocaleString();
        return <p>{dateFormatted}</p>;
      })}
    </>
  );
};

Type recursion is limited to 3 levels in the TypeScript SDK. This is to prevent excessive strain on both the type checker and the language server since each nested level adds computational complexity.

Calls on deeper nested columns will still work, but a TypeScript error may be displayed indicating the type cannot be determined.