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-client

v1.1.0

Published

Official TypeScript/JavaScript client for BaseFlow - a powerful BaaS with OAuth authentication, RPC functions, database indexes, real-time features, and Supabase-compatible API

Readme

baseflow-client

npm version TypeScript License: MIT

The official TypeScript/JavaScript client for BaseFlow - a powerful Backend-as-a-Service (BaaS) platform with advanced query capabilities, real-time features, and Supabase-compatible API.

🚀 Features

  • Advanced Query Builder: Supabase-like API with 20+ filter methods
  • Smart JOINs: Automatic foreign key detection and relationship queries
  • Real-time Subscriptions: Listen to database changes in real-time
  • Authentication: Email/password + OAuth (GitHub, Google)
  • OAuth Providers: Third-party sign-in with GitHub and Google
  • RPC Functions: Call server-side functions remotely
  • Database Indexes: Create and manage indexes for performance optimization
  • File Storage: Upload, manage, and serve files
  • TypeScript First: Fully typed with excellent IntelliSense support
  • Universal: Works in browsers, Node.js, React Native, and edge environments

📦 Installation

npm install baseflow-client
yarn add baseflow-client
pnpm add baseflow-client

🏃‍♂️ Quick Start

1. Initialize the Client

import { createClient } from 'baseflow-client';

const baseflow = createClient({
  url: 'https://your-project.baseflow.cloud',
  apiKey: 'your-api-key'
});

2. Query Your Database

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

// Advanced query with JOINs
const { data, error } = await baseflow
  .from('posts')
  .select('title, content, author:users(name, email)')
  .eq('published', true)
  .order('created_at', { ascending: false })
  .limit(10);

3. Insert Data

const { data, error } = await baseflow
  .from('posts')
  .insert({
    title: 'Hello BaseFlow!',
    content: 'This is my first post.',
    author_id: 1
  });

4. Authentication

// Sign up with email/password
const { user, session, error } = await baseflow.auth.signUp(
  '[email protected]',
  'password123',
  { name: 'John Doe' }
);

// Sign in with email/password
const { user, session, error } = await baseflow.auth.signInWithPassword({
  email: '[email protected]',
  password: 'password123'
});

// Sign in with OAuth (GitHub or Google)
const { data } = await baseflow.auth.signInWithOAuth('github');
window.location.href = data.url; // Redirect to GitHub

// Handle OAuth callback
const result = await baseflow.auth.handleOAuthCallback(code, 'github');
console.log('User:', result.data.user);

// Listen to auth changes
baseflow.auth.onAuthStateChange((event) => {
  console.log('Auth event:', event.type, event.user);
});

5. File Storage

// Upload file
const { data, error } = await baseflow.storage.upload(
  'avatars/user-123.jpg',
  fileBuffer,
  { mimetype: 'image/jpeg' }
);

// Get public URL
const { data: urlData } = await baseflow.storage.getUrl('avatars/user-123.jpg');

6. RPC Functions

// Call a remote procedure
const { data, error } = await baseflow.rpc('calculate_total', {
  user_id: 123,
  start_date: '2024-01-01'
});

// Create a function
await baseflow.createFunction('hello_world', `
  return { message: 'Hello, ' + params.name };
`, {
  language: 'javascript',
  parameters: [{ name: 'name', type: 'string' }]
});

7. Database Indexes

// Create an index for better query performance
const { data, error } = await baseflow.createIndex('users', ['email'], {
  unique: true,
  name: 'idx_users_email'
});

// List all indexes
const { data: indexes } = await baseflow.listIndexes('users');

// Drop an index
await baseflow.dropIndex('idx_users_email');

📚 API Reference

Database Operations

Query Methods

  • select(columns) - Select specific columns (supports JOINs)
  • insert(data) - Insert new records
  • update(data) - Update existing records
  • delete() - Delete records

Filter Methods

  • eq(column, value) - Equal to
  • neq(column, value) - Not equal to
  • gt(column, value) - Greater than
  • gte(column, value) - Greater than or equal
  • lt(column, value) - Less than
  • lte(column, value) - Less than or equal
  • like(column, pattern) - Pattern matching
  • ilike(column, pattern) - Case-insensitive pattern matching
  • in(column, values) - Match any value in array
  • contains(column, value) - Contains value
  • textSearch(column, query) - Full-text search

Query Modifiers

  • order(column, options) - Sort results
  • limit(count) - Limit number of results
  • range(from, to) - Get specific range
  • single() - Return single row
  • maybeSingle() - Return single row or null

Authentication

// Email/Password Authentication
baseflow.auth.signUp(email, password, options?)
baseflow.auth.signInWithPassword(credentials)
baseflow.auth.signOut()
baseflow.auth.getUser()
baseflow.auth.getSession()
baseflow.auth.onAuthStateChange(callback)

// OAuth Authentication
baseflow.auth.signInWithOAuth(provider, options?)  // provider: 'github' | 'google'
baseflow.auth.handleOAuthCallback(code, provider)

Storage

// Available methods
baseflow.storage.upload(path, file, options?)
baseflow.storage.download(path)
baseflow.storage.getUrl(path)
baseflow.storage.list(path?)
baseflow.storage.delete(path)
baseflow.storage.createFolder(path)

RPC & Functions

// Call remote procedures
baseflow.rpc(functionName, params?)

// Function management
baseflow.createFunction(name, definition, options?)
baseflow.listFunctions()
baseflow.getFunction(name)
baseflow.deleteFunction(name)

Database Indexes

// Index management
baseflow.createIndex(table, columns, options?)
baseflow.listIndexes(table?)
baseflow.dropIndex(name)
baseflow.analyzeQuery(query)  // Performance analysis

Advanced Features

// Raw SQL queries
const { data, error } = await baseflow.sql(
  'SELECT * FROM users WHERE created_at > ?',
  ['2024-01-01']
);

// Schema management
const { data, error } = await baseflow.defineSchema({
  users: {
    id: { type: 'INTEGER', primaryKey: true, autoIncrement: true },
    name: { type: 'TEXT', required: true },
    email: { type: 'TEXT', unique: true, required: true }
  }
});

⚡ RPC Functions

Call server-side functions for complex operations:

// Call a function
const { data, error } = await baseflow.rpc('calculate_user_stats', {
  user_id: 123,
  start_date: '2024-01-01',
  end_date: '2024-12-31'
});

console.log('Stats:', data);

// Create a JavaScript function
await baseflow.createFunction('greet_user', `
  return {
    message: 'Hello, ' + params.name + '!',
    timestamp: new Date().toISOString()
  };
`, {
  language: 'javascript',
  parameters: [
    { name: 'name', type: 'string', default: 'Guest' }
  ],
  description: 'Greets a user by name'
});

// Create a SQL function
await baseflow.createFunction('get_active_users', `
  SELECT * FROM users WHERE last_login > datetime('now', '-7 days')
`, {
  language: 'sql',
  returnType: 'table'
});

// List all functions
const { data: functions } = await baseflow.listFunctions();
console.log('Available functions:', functions);

📊 Database Indexes

Optimize query performance with indexes:

// Create a single-column index
await baseflow.createIndex('users', ['email'], {
  unique: true,
  name: 'idx_users_email'
});

// Create a composite index
await baseflow.createIndex('posts', ['user_id', 'created_at'], {
  name: 'idx_posts_user_date'
});

// List all indexes for a table
const { data: indexes } = await baseflow.listIndexes('users');
console.log('Indexes:', indexes);

// Analyze query performance
const { data: analysis } = await baseflow.analyzeQuery(`
  SELECT * FROM posts 
  WHERE user_id = 123 
  ORDER BY created_at DESC
`);

console.log('Query plan:', analysis.queryPlan);
console.log('Estimated rows:', analysis.estimatedRows);
console.log('Uses index:', analysis.usesIndex);

// Drop an index
await baseflow.dropIndex('idx_users_email');

🔗 Advanced Queries

BaseFlow supports sophisticated queries with automatic relationship detection:

// Automatic JOINs based on foreign keys
const { data } = await baseflow
  .from('posts')
  .select(`
    title,
    content,
    author:users(name, email, avatar_url),
    comments(count),
    tags:post_tags(tag:tags(name))
  `)
  .eq('published', true);

// Aggregations
const { data } = await baseflow
  .from('users')
  .select('name, posts(count)')
  .gte('created_at', '2024-01-01');

🔄 Real-time Subscriptions

// Connect to real-time server
await baseflow.realtime.connect();

// Listen to all changes
const unsubscribe = baseflow.realtime.subscribe('posts', (payload) => {
  console.log('Change received!', payload);
  console.log('Event:', payload.event); // INSERT, UPDATE, DELETE
  console.log('New data:', payload.new);
  console.log('Old data:', payload.old);
});

// Unsubscribe when done
unsubscribe();

🔐 OAuth Authentication

BaseFlow supports OAuth authentication with GitHub and Google:

// Sign in with GitHub
async function signInWithGitHub() {
  const { data, error } = await baseflow.auth.signInWithOAuth('github', {
    redirectTo: 'http://localhost:3000/callback'
  });
  
  if (error) {
    console.error('OAuth error:', error);
    return;
  }
  
  // Redirect user to GitHub
  window.location.href = data.url;
}

// Handle OAuth callback (in your callback page)
async function handleCallback() {
  const urlParams = new URLSearchParams(window.location.search);
  const code = urlParams.get('code');
  
  if (code) {
    const { data, error } = await baseflow.auth.handleOAuthCallback(code, 'github');
    
    if (error) {
      console.error('Authentication failed:', error);
      return;
    }
    
    console.log('User:', data.user);
    console.log('Session:', data.session);
    
    // User is now authenticated!
  }
}

// Sign in with Google
async function signInWithGoogle() {
  const { data } = await baseflow.auth.signInWithOAuth('google');
  window.location.href = data.url;
}

OAuth Setup

To use OAuth, configure your providers in the BaseFlow server:

# .env
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret

See the OAuth Setup Guide for detailed instructions.

🛠️ TypeScript Support

BaseFlow is built with TypeScript and provides excellent type safety:

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

const { data, error } = await baseflow
  .from<User>('users')
  .select('*')
  .eq('id', 1)
  .single();

// data is typed as User | null
// error is typed as BaseFlowError | null

🌐 Environment Support

BaseFlow client works in all JavaScript environments:

  • Browsers (Chrome, Firefox, Safari, Edge)
  • Node.js (16+)
  • React Native
  • Next.js (App Router & Pages Router)
  • Vite
  • Webpack
  • Edge Runtime (Vercel, Cloudflare Workers)

📖 Examples

React Integration

import { createClient } from 'baseflow-client';
import { useEffect, useState } from 'react';

const baseflow = createClient({
  url: process.env.NEXT_PUBLIC_BASEFLOW_URL!,
  apiKey: process.env.NEXT_PUBLIC_BASEFLOW_ANON_KEY!
});

function UsersList() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function fetchUsers() {
      const { data, error } = await baseflow
        .from('users')
        .select('*')
        .order('created_at', { ascending: false });
      
      if (data) setUsers(data);
      setLoading(false);
    }

    fetchUsers();
  }, []);

  if (loading) return <div>Loading...</div>;

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name} - {user.email}</li>
      ))}
    </ul>
  );
}

Next.js API Route

// pages/api/users.ts
import { createClient } from 'baseflow-client';

const baseflow = createClient({
  url: process.env.BASEFLOW_URL!,
  apiKey: process.env.BASEFLOW_SERVICE_ROLE_KEY!
});

export default async function handler(req, res) {
  if (req.method === 'GET') {
    const { data, error } = await baseflow
      .from('users')
      .select('*');
    
    if (error) {
      return res.status(400).json({ error: error.message });
    }
    
    return res.json({ users: data });
  }
}

🔧 Configuration

Client Options

interface BaseFlowClientOptions {
  url: string;                    // Your BaseFlow project URL
  apiKey: string;                 // Your project API key
  headers?: Record<string, string>; // Additional headers
  fetch?: typeof fetch;           // Custom fetch implementation
}

Environment Variables

# .env.local
NEXT_PUBLIC_BASEFLOW_URL=https://your-project.baseflow.cloud
NEXT_PUBLIC_BASEFLOW_ANON_KEY=your-anon-key
BASEFLOW_SERVICE_ROLE_KEY=your-service-role-key

🚨 Error Handling

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('Users:', data);
}

🆚 Comparison with Other BaaS

| Feature | BaseFlow | Supabase | Firebase | PlanetScale | |---------|----------|----------|----------|-------------| | Advanced JOINs | ✅ | ✅ | ❌ | ✅ | | Auto FK Detection | ✅ | ❌ | ❌ | ❌ | | OAuth (GitHub/Google) | ✅ | ✅ | ✅ | ❌ | | RPC Functions | ✅ | ✅ | ✅ | ❌ | | Database Indexes | ✅ | ✅ | ✅ | ✅ | | TypeScript First | ✅ | ✅ | ⚠️ | ✅ | | Local Development | ✅ | ✅ | ❌ | ❌ | | Real-time | ✅ | ✅ | ✅ | ❌ | | File Storage | ✅ | ✅ | ✅ | ❌ | | Edge Functions | 🔄 | ✅ | ✅ | ❌ | | SQLite Backend | ✅ | ❌ | ❌ | ❌ |

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

📄 License

MIT License - see the LICENSE file for details.

🔗 Links


Built with ❤️ by the BaseFlow team