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

@aiwa/firekit

v1.3.0

Published

AIWA's managed Firebase SDK for multi-tenant applications

Downloads

577

Readme

Firekit 🔥

AIWA's managed Firebase SDK for multi-tenant applications. Zero configuration, complete isolation.

Features

  • Zero Config - Automatic Firebase initialization from AIWA backend
  • 🔒 Multi-Tenant Isolation - Each app is completely isolated via collection paths
  • 🔐 Built-in Auth - Email/password authentication with custom claims
  • Real-time Updates - Live data subscriptions
  • 🎯 Type-Safe - Full TypeScript support
  • 🚀 Edge-Ready - Works with Vercel Edge Functions
  • 🔐 Secure - Firebase credentials managed server-side, never exposed to users

How It Works

  1. Your app calls createDatabase({ projectId })
  2. Firekit validates projectId with AIWA backend
  3. Backend returns userId, appId, and Firebase credentials
  4. Firekit initializes with returned credentials
  5. All data isolated to /users/{userId}/apps/{appId}/data/

Security: Firebase credentials stay on AIWA's servers. User apps never see them.

Installation

npm install @aiwa/firekit
# or
pnpm add @aiwa/firekit
# or
yarn add @aiwa/firekit

Environment Variables

Add to your .env.local:

NEXT_PUBLIC_PROJECT_ID=your-project-id

That's it. Firebase credentials are automatically retrieved from AIWA's secure backend.

Quick Start

import { createDatabase, createAuth } from '@aiwa/firekit'

// Initialize database (multi-tenant isolated)
const db = await createDatabase({
  projectId: process.env.NEXT_PUBLIC_PROJECT_ID!,
})

// Initialize auth
const auth = await createAuth({
  projectId: process.env.NEXT_PUBLIC_PROJECT_ID!,
})

Database Operations

Create

const post = await db.create('posts', {
  title: 'Hello World',
  content: 'My first post',
  published: true,
})

Read

// Get single document
const post = await db.read('posts', 'post-id')

// Get all documents
const posts = await db.getAll('posts')

// Query with filters
const publishedPosts = await db.query('posts', {
  where: [{ field: 'published', operator: '==', value: true }],
  orderBy: { field: 'createdAt', direction: 'desc' },
  limit: 10,
})

Update

await db.update('posts', 'post-id', {
  title: 'Updated Title',
})

Delete

await db.delete('posts', 'post-id')

Real-time Subscriptions

const unsubscribe = db.subscribe('posts', (posts) => {
  console.log('Posts updated:', posts)
})

// Clean up when done
unsubscribe()

Authentication

Sign Up

const { user, token } = await auth.signUp(
  '[email protected]',
  'password123',
  'John Doe', // optional display name
)

Sign In

const { user, token } = await auth.signIn('[email protected]', 'password123')

Sign Out

await auth.signOut()

Auth State Listener

const unsubscribe = auth.onAuthStateChanged((user) => {
  if (user) {
    console.log('Signed in:', user.email)
  } else {
    console.log('Signed out')
  }
})

Password Reset

await auth.resetPassword('[email protected]')

React Example

'use client'

import { createDatabase, createAuth } from 'firekit'
import { useEffect, useState } from 'react'

const db = createDatabase({
  userId: process.env.NEXT_PUBLIC_AIWA_USER_ID!,
  appId: process.env.NEXT_PUBLIC_AIWA_APP_ID!,
})

const auth = createAuth({
  appId: process.env.NEXT_PUBLIC_AIWA_APP_ID!,
})

export default function TodoApp() {
  const [user, setUser] = useState(null)
  const [todos, setTodos] = useState([])

  // Auth listener
  useEffect(() => {
    return auth.onAuthStateChanged(setUser)
  }, [])

  // Real-time todos subscription
  useEffect(() => {
    if (!user) return

    return db.subscribe(
      'todos',
      setTodos,
      {
        where: [{ field: 'userId', operator: '==', value: user.uid }],
        orderBy: { field: '_createdAt', direction: 'desc' },
      },
    )
  }, [user])

  const addTodo = async (title: string) => {
    await db.create('todos', {
      title,
      completed: false,
      userId: user.uid,
    })
  }

  const toggleTodo = async (id: string, completed: boolean) => {
    await db.update('todos', id, { completed })
  }

  if (!user) return <SignInForm />

  return <TodoList todos={todos} onAdd={addTodo} onToggle={toggleTodo} />
}

Multi-Tenant Isolation

Firekit automatically isolates data using collection paths:

/users/{userId}/apps/{appId}/data/{collection}/{docId}

Example:

  • User A's app: /users/user-a/apps/app-123/data/posts/post-1
  • User B's app: /users/user-b/apps/app-456/data/posts/post-1

Complete isolation - User A's app users cannot access User B's app data.

Security Rules

Firekit enforces security via Firebase Security Rules with custom claims:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId}/apps/{appId}/data/{collection}/{document=**} {
      // AIWA user (app owner) has full access
      allow read, write: if request.auth.token.userId == userId;

      // App end-users have access based on appId
      allow read, write: if request.auth.token.appId == appId
                         && request.auth != null;
    }
  }
}

Error Handling

import { FirekitDatabaseError, FirekitAuthError } from 'firekit'

try {
  await db.create('posts', { title: 'Hello' })
} catch (error) {
  if (error instanceof FirekitDatabaseError) {
    console.error('Database error:', error.message, error.code)
  }
}

try {
  await auth.signIn('email', 'password')
} catch (error) {
  if (error instanceof FirekitAuthError) {
    console.error('Auth error:', error.message, error.code)
  }
}

API Reference

Database Methods

  • create(collection, data) - Create document
  • set(collection, id, data, merge?) - Set document with ID
  • read(collection, id) - Read single document
  • query(collection, options?) - Query documents
  • getAll(collection) - Get all documents
  • update(collection, id, data) - Update document
  • delete(collection, id) - Delete document
  • subscribe(collection, callback, options?) - Real-time subscription
  • subscribeToDoc(collection, id, callback) - Single document subscription
  • batchCreate(collection, items) - Batch create
  • count(collection, options?) - Count documents

Auth Methods

  • signUp(email, password, displayName?) - Register user
  • signIn(email, password) - Sign in user
  • signOut() - Sign out
  • resetPassword(email) - Send reset email
  • updateProfile(data) - Update profile
  • updateEmail(email) - Update email
  • updatePassword(password) - Update password
  • onAuthStateChanged(callback) - Listen to auth changes
  • getIdToken(forceRefresh?) - Get ID token
  • isAuthenticated() - Check auth status

License

Apache-2.0