npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@leapcell/leapcell-js

v0.0.14

Published

leapcell js sdk

Readme

Documentation

See the Doc

See the API reference

Installation

The SDK supports both JavaScript and TypeScript, and you can install it using npm.

npm install @leapcell/leapcell-js

Preparation

Leapcell uses an API Token to access the Leapcell API. You can learn more about the API Token here.

Quick Start

import { Leapcell } from "@leapcell/leapcell-js";

// Init client with token from env
const client = new Leapcell({
  apiKey: process.env.LEAPCELL_API_KEY!,
});

// Init table instance
// TABLE_ID is your table ID, for example, if your table is leapcell.io/issac/blog/table/12345678, then TABLE_ID is 12345678.
// REPO_NAME is your repository name, for example, if your repository is leapcell.io/issac/blog, then REPO_NAME is issac/blog.
const table = api.repo("{{REPO_NAME}}").table("{{TABLE_ID}}");

// Create record
const record = await table.records.create({
  title: "hello issac",
});

// Update record
const record = await table.records.updateById({
  id: "7ba4d5f1-8c85-4155-8deb-6d7ad88977f3",
  data: { title: "hello issac again" },
});

// Get record by id
const record = await table.records.findById(
  "2bc243ee-7e77-4f5e-b5b2-2da9d70c6779"
);

// Delete record by id
const record = await table.records.deleteById(
  "7ba4d5f1-8c85-4155-8deb-6d7ad88977f3"
);

// Get all records
const records = await table.records.findMany({});

// Search records, like a search engine
const records = await table.records.search({
  query: "why leapcell",
});

// Get records if the title is "hello."
const records = await table.records.findMany({
  where: {
    title: {
      eq: "leapcell",
    },
  },
});

// Get records with sorting
const records2 = await table.records.findMany({
  where: {
    name: {
      eq: "leapcell",
    },
  },
  orderBy: {
    name: "asc",
  },
});

// Update records
const records = await table.records.updateMany({
  where: {
    name: {
      eq: "issac",
    },
  },
  data: {
    category: "blog",
  },
});

// Delete records
const records = await table.records.deleteMany({
  where: {
    name: {
      neq: "issac",
    },
  },
});

// Bulk create
const records = await table.records.createMany([
  {
    name: "Alice",
  },
  {
    name: "Bob",
  },
]);

// Count all records
const count = await table.records.count();

Usage

Init Client

You can place the API Token in the environment variable or pass it directly.

REPO_NAME is your repository name, for example, if your repository is leapcell.io/issac/blog, then REPO_NAME is issac/blog.

TABLE_ID is your table ID, for example, if your table is leapcell.io/issac/blog/table/12345678, then TABLE_ID is 12345678.

The table defaults to using the table name, which is the name you set in the table. If you want to use the table ID, you can set name_type to id.

import { Leapcell } from "@leapcell/leapcell-js";

// Init client with token from env
const client = new Leapcell({
  apiKey: process.env.LEAPCELL_API_KEY!,
});

// Init table instance
const table = api.repo("{{REPO_NAME}}").table("{{TABLE_ID}}");

// Init table instance with table id
// const table = api.repo("{{REPO_NAME}}").table("{{TABLE_ID}}", "id");

Get Table Meta Info

// Get table meta info
const meta = await table.meta();

Create Record

Leapcell automatically converts data based on the table's field types. If conversion fails, an exception is thrown.

// Create record
const record = await table.records.create({
  title: "hello issac",
});

Update Record

// Update record
const record = await table.records.updateById({
  id: "7ba4d5f1-8c85-4155-8deb-6d7ad88977f3",
  data: { title: "hello issac again" },
});
console.log("records", record);

Get Record By ID

const record = await table.records.findById(
  "2bc243ee-7e77-4f5e-b5b2-2da9d70c6779"
);
console.log("record", record);

Delete Record By ID

const record = await table.records.deleteById(
  "7ba4d5f1-8c85-4155-8deb-6d7ad88977f3"
);
console.log("records", record);

Get All Records

const records = await table.records.findMany({});

Get Record By Filter

Leapcell supports various query methods. If you're familiar with Prisma, you'll find the usage quite similar.

Get records if the title is "hello."

const records = await table.records.findMany({
  where: {
    title: {
      eq: "hello",
    },
  },
});
console.log("records", records);

AND

Get records if the title is "hello" and the category is "tutorial."

const records = await table.records.findMany({
  where: {
    AND: {
      title: {
        eq: "hello",
      },
      category: {
        eq: "tutorial",
      },
    },
  },
});
console.log("records", records);

OR

Get records if the title is "hello" or the category is "tutorial."

const records = await table.records.findMany({
  where: {
    OR: {
      title: {
        eq: "hello",
      },
      category: {
        eq: "tutorial",
      },
    },
  },
});
console.log("records", records);

Field Operators

For the supported field operators, you can refer to Field Operators.

The mapping between op and JS operators is as follows:

// op: eq
{
    "title": {
        eq: 'hello',
    },
}

// op: gt
{
    "title": {
        gt: 'hello',
    },
}

// op: gte
{
    "title": {
        gte: 'hello',
    },
}

// op: lt
{
    "title": {
        lt: 'hello',
    },
}

// op: lte
{
    "title": {
        lte: 'hello',
    },
}

// op: neq
{
    "title": {
        neq: 'hello',
    },
}

// op: contain
{
    "title": {
        contain: 'hello',
    },
}

// op: in
{
    "title": {
        in: ['hello', 'world'],
    },
}

// op: not_in

{
    "title": {
        not_in: ['hello', 'world'],
    },
}

// op: is_null
{
    "title": {
        is_null: true,
    },
}

// op: is_not_null
{
    "title": {
        is_not_null: true,
    },
}

Get Records and Sort

// Get records with sorting
const records2 = await table.records.findMany({
  where: {
    name: {
      eq: "leapcell",
    },
  },
  orderBy: {
    name: "asc",
  },
});

Get Records and Pagination

Get records with a limit of 10 and an offset of 0.

const records2 = await table.records.findMany({
  where: {
    name: {
      eq: "issac",
    },
  },
  orderBy: {
    name: "asc",
  },
  offset: 0,
  limit: 10,
});

Update Record By Filter

// Update records
const records = await table.records.updateMany({
  where: {
    name: {
      eq: "issac",
    },
  },
  data: {
    category: "blog",
  },
});
console.log("records", records);

Delete Record By Filter

// Delete records
const records = await table.records.deleteMany({
  where: {
    name: {
      neq: "issac",
    },
  },
});
console.log("records", records);

Bulk Create

// Bulk create
const records = await table.records.createMany([
  {
    name: "Alice",
  },
  {
    name: "Bob",
  },
]);
console.log("records", records);

Search

By default, the search functionality covers all fields. If you want to specify particular fields, you can use the fields parameter.

Similar to a search engine, Leapcell tokenizes the keywords and performs searches. For instance, when you search for "hello issac," Leapcell will first search for "hello" and then for "issac," merging the results of both searches.

// Search for "hello"
const records = await table.records.search({
  query: "hello",
});
console.log("records", records);

// Search for "hello" and "jude"
const records = await table.records.search({
  query: "hello jude",
});
console.log("records", records);

// Search in the "title" field
const records = await table.records.search({
  query: "hello jude",
  search_fields: "title",
});
console.log("records", records);

// Pagination
const records = await table.records.search({
  query: "hello jude",
  search_fields: "title",
  offset: 0,
  limit: 10,
});
console.log("records", records);

Image Upload

Leapcell supports image uploads. You can upload images to Leapcell and save the image URLs to the table.

Images will be uploaded to the CDN.

const image = await axios.get(
  "https://leapcell-dev-bucket.s3.amazonaws.com/920417ee6a70435084fe6b40d58dad4e.jpeg",
  {
    responseType: "arraybuffer",
  }
);
const imageItem = await table.file.upload(image.data);
console.log("imageItem", imageItem);

Aggregate

Count

// Count all records
const count = await table.records.count();
console.log("count", count);

// Count records where the name is "issac"
const count2 = await table.records.count({
  where: {
    name: {
      eq: "issac",
    },
  },
});
console.log("count", count2);