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

@picobase_app/client

v1.0.2

Published

PicoBase client SDK — auth, database, storage, and realtime for your apps

Readme

@picobase_app/client

TypeScript SDK for PicoBase — add auth, database, realtime, and file storage to your app.

Install

npm install @picobase_app/client

⚠️ Important: Always install @picobase_app/client. If you accidentally installed pocketbase, remove it — that's an internal dependency, not the user-facing SDK.

Quickstart

import { createClient } from '@picobase_app/client'

const pb = createClient('https://myapp.picobase.com', 'pbk_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')

Get your URL and API key from the PicoBase dashboard.

Authentication

// Sign up a new user
const { token, record } = await pb.auth.signUp({
  email: '[email protected]',
  password: 'securepassword',
  name: 'Jane Doe',
})

// Sign in
const { token, record } = await pb.auth.signIn({
  email: '[email protected]',
  password: 'securepassword',
})

// OAuth (Google, GitHub, etc. — configure providers in the dashboard)
const { token, record } = await pb.auth.signInWithOAuth({
  provider: 'google',
})

// Check current user
const user = pb.auth.user       // RecordModel | null
const isValid = pb.auth.isValid // boolean

// Listen to auth changes
const unsubscribe = pb.auth.onStateChange((event, record) => {
  // event: 'SIGNED_IN' | 'SIGNED_OUT' | 'TOKEN_REFRESHED'
  console.log(event, record?.email)
})

// Password reset
await pb.auth.requestPasswordReset('[email protected]')

// Sign out
pb.auth.signOut()

Database (Collections)

// List records with pagination, filtering, and sorting
const result = await pb.collection('posts').getList(1, 20, {
  filter: 'published = true',
  sort: '-created',
  expand: 'author',
})
// result.items, result.totalItems, result.totalPages

// Get a single record
const post = await pb.collection('posts').getOne('RECORD_ID')

// Find first match
const admin = await pb.collection('users').getFirstListItem('role = "admin"')

// Get all records (auto-paginates — use with caution on large collections)
const allPosts = await pb.collection('posts').getFullList({
  filter: 'published = true',
})

// Create
const newPost = await pb.collection('posts').create({
  title: 'Hello World',
  content: 'My first post',
  published: true,
})

// Update
const updated = await pb.collection('posts').update('RECORD_ID', {
  title: 'Updated Title',
})

// Delete
await pb.collection('posts').delete('RECORD_ID')

TypeScript generics

interface Post {
  id: string
  title: string
  content: string
  published: boolean
  created: string
  updated: string
}

const posts = await pb.collection<Post>('posts').getList(1, 20)
// posts.items is Post[]

File uploads

const formData = new FormData()
formData.append('title', 'Photo post')
formData.append('image', fileInput.files[0])

const record = await pb.collection('posts').create(formData)

Realtime

// Subscribe to all changes on a collection
const unsubscribe = await pb.collection('posts').subscribe((event) => {
  console.log(event.action, event.record) // 'create' | 'update' | 'delete'
})

// Subscribe to a specific record
const unsubscribe = await pb.collection('posts').subscribeOne('RECORD_ID', (event) => {
  console.log(event.action, event.record)
})

// Unsubscribe
await unsubscribe()

// Or use the realtime module directly
const unsub = await pb.realtime.subscribe('posts', (event) => {
  console.log(event)
})

// Disconnect all realtime subscriptions
await pb.realtime.disconnectAll()

RPC (Remote Procedure Calls)

Call custom server-side functions using the .rpc() method. This is especially useful for Supabase migrations.

// Simple RPC call
const result = await pb.rpc('calculate_cart_total', {
  cart_id: '123'
})

// Complex RPC with typed response
interface DashboardStats {
  posts: number
  comments: number
  followers: number
}

const stats = await pb.rpc<DashboardStats>('get_dashboard_stats', {
  user_id: currentUser.id
})
// stats.posts, stats.comments, stats.followers are typed!

// Common patterns
await pb.rpc('increment_views', { post_id: '123' })
const results = await pb.rpc('search_products', {
  query: 'laptop',
  min_price: 500,
  category: 'electronics'
})

RPC calls are mapped to custom endpoints at /api/rpc/{functionName}. You can implement these routes in your PicoBase instance.

File Storage

PicoBase stores files as fields on records. Use the storage module to get URLs.

const user = await pb.collection('users').getOne('USER_ID')

// Get file URL
const url = pb.storage.getFileUrl(user, 'avatar.jpg')

// Get thumbnail
const thumb = pb.storage.getFileUrl(user, 'avatar.jpg', { thumb: '100x100' })

// Protected files — get a temporary token first
const token = await pb.storage.getFileToken()
const protectedUrl = pb.storage.getFileUrl(user, 'document.pdf', { token })

Admin API (Collection Management)

The SDK provides an admin module that allows you to programmatically manage your PicoBase collections. This requires an admin API key to be used during client initialization.

// Initializing with an admin API key
const adminPb = createClient('https://myapp.picobase.com', 'pbk_admin_xxxxxxxx')

// Create a new collection
const usersCollection = await adminPb.admin.createCollection({
  name: "custom_users",
  type: "base",
  schema: [
    { name: "full_name", type: "text", required: true },
    { name: "age", type: "number" }
  ]
})

// List all collections
const collections = await adminPb.admin.listCollections()

// Get a single collection
const collection = await adminPb.admin.getCollection('custom_users')

// Update an existing collection
const updated = await adminPb.admin.updateCollection('custom_users', {
  name: "users_updated"
})

// Delete a collection
const success = await adminPb.admin.deleteCollection('users_updated')

Advanced

Custom auth collection

// If you use a custom auth collection instead of 'users'
pb.auth.setCollection('members')
await pb.auth.signIn({ email: '[email protected]', password: 'pass' })

Raw access (advanced)

The underlying client instance is exposed for advanced use cases.

// Access the internal client directly
const health = await pb.pb.health.check()

// Custom API endpoint
const result = await pb.send('/api/custom-endpoint', { method: 'POST', body: { foo: 'bar' } })

Cold-start handling

PicoBase instances may be paused when idle. The SDK automatically retries with exponential backoff (2s, 4s, 8s) when it receives a 503 response. You can configure this:

const pb = createClient('https://myapp.picobase.com', 'pbk_...', {
  maxColdStartRetries: 5,  // default: 3
})

Error handling

Every SDK error includes a code and fix property with actionable suggestions:

import {
  PicoBaseError,
  AuthorizationError,
  InstanceUnavailableError,
  CollectionNotFoundError,
  RecordNotFoundError,
  ConfigurationError,
  RpcError,
} from '@picobase_app/client'

try {
  await pb.collection('posts').getList()
} catch (err) {
  if (err instanceof PicoBaseError) {
    console.log(err.message)  // "Collection 'posts' not found."
    console.log(err.code)     // "COLLECTION_NOT_FOUND"
    console.log(err.fix)      // "Make sure the collection 'posts' exists..."
  }
}

Error types:

| Error | Code | When | |---|---|---| | ConfigurationError | CONFIGURATION_ERROR | Missing URL, API key, or bad config | | AuthorizationError | UNAUTHORIZED | Invalid or missing API key | | CollectionNotFoundError | COLLECTION_NOT_FOUND | Collection doesn't exist | | RecordNotFoundError | RECORD_NOT_FOUND | Record ID not found | | InstanceUnavailableError | INSTANCE_UNAVAILABLE | Instance down after retries | | RpcError | RPC_ERROR | RPC function call failed (includes endpoint-specific fix hints) | | RequestError | REQUEST_FAILED | Generic HTTP error (includes status-specific fix hints) |

Typed collections with picobase typegen

Run picobase typegen to generate types from your schema. The generated file includes a typed client:

import { pb } from './src/types/picobase'

// Collection names autocomplete, record fields are typed
const result = await pb.collection('posts').getList(1, 20)
result.items[0].title  // string — fully typed!

API Reference

createClient(url, apiKey, options?)

| Parameter | Type | Description | |---|---|---| | url | string | Your PicoBase instance URL | | apiKey | string | API key from the dashboard (starts with pbk_) | | options.maxColdStartRetries | number | Max retries on 503. Default: 3 | | options.lang | string | Accept-Language header. Default: 'en-US' |

Modules

| Module | Access | Description | |---|---|---| | pb.auth | PicoBaseAuth | Sign up, sign in, OAuth, session management | | pb.collection(name) | PicoBaseCollection | CRUD operations on a collection | | pb.realtime | PicoBaseRealtime | Realtime subscriptions | | pb.storage | PicoBaseStorage | File URLs and tokens | | pb.pb | PocketBase | Underlying internal client instance |