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 🙏

© 2025 – Pkg Stats / Ryan Hefner

baseflow-local-client

v1.0.2

Published

Official TypeScript/JavaScript client for BaseFlow Local - a local-first BaaS with SQLite database, authentication, file storage, and real-time features

Readme

BaseFlow Local Client

Official TypeScript/JavaScript client for BaseFlow Local - a local-first Backend-as-a-Service with SQLite database, authentication, file storage, and real-time features.

Installation

npm install @baseflow/local-client

Quick Start

import { createClient } from '@baseflow/local-client';

// Create client (connects to local server)
const baseflow = createClient({
  url: 'http://localhost:5555', // Optional, defaults to localhost:5555
  apiKey: 'your-api-key-here'    // Optional: API key for authentication
});

// Query data
const { data, error } = await baseflow
  .from('users')
  .select('*')
  .eq('status', 'active');

// Insert data
await baseflow.from('posts').insert({
  title: 'Hello World',
  content: 'My first post'
});

// Update data
await baseflow
  .from('users')
  .update({ name: 'Jane Doe' })
  .eq('id', 1);

// Delete data
await baseflow
  .from('posts')
  .delete()
  .eq('id', 123);

API Key Authentication

BaseFlow Local generates an API key for each project. You can find your API key in the .baseflow/api-keys.json file or by visiting http://localhost:5555/api/keys.

const baseflow = createClient({
  url: 'http://localhost:5555',
  apiKey: 'bf_local_your_api_key_here'
});

Alternatively, you can pass the API key in headers:

const baseflow = createClient({
  url: 'http://localhost:5555',
  headers: {
    'x-api-key': 'bf_local_your_api_key_here'
  }
});

Features

  • 🗄️ Database Operations - Full CRUD with query builder
  • 🔐 Authentication - JWT-based auth with signup/login
  • 📁 File Storage - Upload, download, and manage files
  • 🔄 Real-time - Subscribe to database changes
  • 🚀 TypeScript - Full type safety and IntelliSense
  • 🌐 Universal - Works in Node.js and browsers

Authentication

// Register a new user
const { data, error } = await baseflow.auth.signUp({
  email: '[email protected]',
  password: 'SecurePassword123',
  name: 'John Doe'
});

// Login
const { data, error } = await baseflow.auth.signInWithPassword({
  email: '[email protected]',
  password: 'SecurePassword123'
});

// Get current user
const { data, error } = await baseflow.auth.getUser();

// Logout
await baseflow.auth.signOut();

// Listen to auth state changes
const unsubscribe = baseflow.auth.onAuthStateChange((event) => {
  if (event.type === 'SIGNED_IN') {
    console.log('User signed in:', event.user);
  }
});

File Storage

// Upload file (Node.js)
const fs = require('fs');
const fileBuffer = fs.readFileSync('image.jpg');

const { data, error } = await baseflow.storage.upload(fileBuffer, {
  filename: 'image.jpg',
  folder: 'images',
  isPublic: true
});

// Upload file (Browser)
const file = document.getElementById('input').files[0];
const { data, error } = await baseflow.storage.upload(file, {
  folder: 'uploads',
  isPublic: true
});

// List files
const { data, error } = await baseflow.storage.list('images');

// Get file URL
const url = baseflow.storage.getUrl('images/photo.jpg');

// Delete file
await baseflow.storage.delete(fileId);
  • 🔍 Advanced Queries - Filtering, sorting, pagination
  • 📦 TypeScript Support - Full type safety
  • 🎯 Supabase-like API - Familiar developer experience

Database Operations

Select

// Select all
const { data } = await baseflow.from('users').select('*');

// Select specific columns
const { data } = await baseflow.from('users').select('id, name, email');

// With filters
const { data } = await baseflow
  .from('users')
  .select('*')
  .eq('status', 'active')
  .gt('age', 18);

// With sorting
const { data } = await baseflow
  .from('posts')
  .select('*')
  .order('created_at', { ascending: false });

// With pagination
const { data } = await baseflow
  .from('users')
  .select('*')
  .range(0, 9); // First 10 records

// Single record
const { data } = await baseflow
  .from('users')
  .select('*')
  .eq('id', 1)
  .single();

Insert

// Insert single record
const { data, error } = await baseflow.from('users').insert({
  name: 'John Doe',
  email: '[email protected]'
});

// Insert multiple records
const { data, error } = await baseflow.from('users').insert([
  { name: 'Alice', email: '[email protected]' },
  { name: 'Bob', email: '[email protected]' }
]);

Update

// Update with filter
const { data, error } = await baseflow
  .from('users')
  .update({ status: 'inactive' })
  .eq('last_login', null);

// Update single record
const { data, error } = await baseflow
  .from('users')
  .update({ name: 'Jane Smith' })
  .eq('id', 1);

Delete

// Delete with filter
const { data, error } = await baseflow
  .from('posts')
  .delete()
  .eq('status', 'draft');

// Delete single record
const { data, error } = await baseflow
  .from('users')
  .delete()
  .eq('id', 123);

Filters

// Equals
.eq('column', 'value')

// Not equals
.neq('column', 'value')

// Greater than
.gt('column', 10)

// Greater than or equal
.gte('column', 10)

// Less than
.lt('column', 10)

// Less than or equal
.lte('column', 10)

// Like (pattern matching)
.like('column', '%pattern%')

// Case-insensitive like
.ilike('column', '%pattern%')

// Is null
.is('column', null)

// In array
.in('column', [1, 2, 3])

// Match multiple conditions
.match({ status: 'active', role: 'admin' })

Authentication

Sign Up

const { data, error } = await baseflow.auth.signUp({
  email: '[email protected]',
  password: 'securepassword',
  name: 'John Doe' // Optional
});

if (data) {
  console.log('User:', data.user);
  console.log('Token:', data.token);
}

Sign In

const { data, error } = await baseflow.auth.signInWithPassword({
  email: '[email protected]',
  password: 'securepassword'
});

if (data) {
  console.log('Logged in:', data.user);
}

Get Current User

const { data, error } = await baseflow.auth.getUser();

if (data) {
  console.log('Current user:', data.user);
}

Sign Out

await baseflow.auth.signOut();

Auth State Changes

const unsubscribe = baseflow.auth.onAuthStateChange((event) => {
  if (event.type === 'SIGNED_IN') {
    console.log('User signed in:', event.user);
  } else if (event.type === 'SIGNED_OUT') {
    console.log('User signed out');
  }
});

// Unsubscribe when done
unsubscribe();

Manual Session Management

// Set session manually (e.g., from localStorage)
baseflow.auth.setSession({
  token: 'your-jwt-token',
  user: { id: 1, email: '[email protected]' }
});

// Get current session
const session = baseflow.auth.getSession();
console.log(session.token, session.user);

File Storage

Upload File

// From file input
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];

const { data, error } = await baseflow.storage.upload(file, {
  folder: 'images',
  isPublic: true
});

if (data) {
  console.log('File uploaded:', data.filename);
  console.log('Public URL:', data.publicUrl);
}

Upload with Node.js

import fs from 'fs';

const fileBuffer = fs.readFileSync('./image.jpg');

const { data, error } = await baseflow.storage.upload(fileBuffer, {
  folder: 'uploads',
  isPublic: false
});

List Files

// List all files
const { data, error } = await baseflow.storage.list();

// List files in folder
const { data, error } = await baseflow.storage.list('images');

if (data) {
  console.log('Files:', data.files);
  console.log('Count:', data.count);
}

Get File URL

const url = baseflow.storage.getUrl('path/to/file.jpg');
console.log('File URL:', url);

Download File

const { data, error } = await baseflow.storage.download('path/to/file.jpg');

Delete File

const { data, error } = await baseflow.storage.delete(fileId);

RPC Functions

Call custom server-side functions:

const { data, error } = await baseflow.rpc('myFunction', {
  param1: 'value1',
  param2: 'value2'
});

Utility Methods

List Tables

const { data, error } = await baseflow.listTables();
console.log('Tables:', data.tables);

Get Schema

const { data, error } = await baseflow.getSchema();
console.log('Schema:', data);

TypeScript Support

The client is fully typed for TypeScript:

interface User {
  id: number;
  name: string;
  email: string;
  created_at: string;
}

// Type-safe queries
const { data, error } = await baseflow
  .from<User>('users')
  .select('*')
  .eq('email', '[email protected]');

// data is typed as User[] | null
if (data) {
  data.forEach(user => {
    console.log(user.name); // TypeScript knows this exists
  });
}

Error Handling

All methods return a response object with data and error:

const { data, error } = await baseflow.from('users').select('*');

if (error) {
  console.error('Error:', error.message);
  console.error('Code:', error.code);
  console.error('Details:', error.details);
} else {
  console.log('Data:', data);
}

Configuration

Custom URL

const baseflow = createClient({
  url: 'http://192.168.1.100:5555' // Custom server URL
});

With Authentication Token

const baseflow = createClient({
  url: 'http://localhost:5555',
  token: 'your-jwt-token' // Pre-authenticated
});

Custom Headers

const baseflow = createClient({
  url: 'http://localhost:5555',
  headers: {
    'X-Custom-Header': 'value'
  }
});

Custom Fetch Implementation

import fetch from 'node-fetch';

const baseflow = createClient({
  url: 'http://localhost:5555',
  fetch: fetch as any
});

Differences from Cloud Client

| Feature | Cloud Client | Local Client | |---------|--------------|--------------| | URL | https://api.baseflow.dev | http://localhost:5555 | | Auth | API Key + Project ID | JWT tokens | | Endpoints | /rest/v1/... | /api/... | | Real-time | Cloud WebSocket | Local WebSocket (coming soon) | | OAuth | Supported | Not supported |

Examples

Complete CRUD Example

import { createClient } from '@baseflow/local-client';

const baseflow = createClient();

// Create
const { data: newUser } = await baseflow.from('users').insert({
  name: 'Alice',
  email: '[email protected]'
});

// Read
const { data: users } = await baseflow
  .from('users')
  .select('*')
  .eq('email', '[email protected]');

// Update
await baseflow
  .from('users')
  .update({ name: 'Alice Smith' })
  .eq('id', newUser.id);

// Delete
await baseflow
  .from('users')
  .delete()
  .eq('id', newUser.id);

Authentication Flow

// Register
const { data: signUpData } = await baseflow.auth.signUp({
  email: '[email protected]',
  password: 'password123',
  name: 'John Doe'
});

// Login
const { data: signInData } = await baseflow.auth.signInWithPassword({
  email: '[email protected]',
  password: 'password123'
});

// Get user
const { data: userData } = await baseflow.auth.getUser();

// Logout
await baseflow.auth.signOut();

File Upload Example

// Browser
const handleUpload = async (event) => {
  const file = event.target.files[0];
  
  const { data, error } = await baseflow.storage.upload(file, {
    folder: 'avatars',
    isPublic: true
  });
  
  if (data) {
    console.log('Uploaded:', data.publicUrl);
  }
};

// Node.js
import fs from 'fs';

const buffer = fs.readFileSync('./document.pdf');
const { data } = await baseflow.storage.upload(buffer, {
  folder: 'documents',
  isPublic: false
});

License

MIT

Links

Support

For questions and support, please visit our GitHub Discussions.