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

@familyctx/supabase

v0.1.4

Published

Supabase adapter for FamilyCtx.

Readme

@familyctx/supabase

Supabase adapter for FamilyCtx with real-time sync, parent authentication, and profile management.

Installation

npm install @familyctx/supabase @familyctx/core @familyctx/react @supabase/supabase-js

Database Setup

Run the SQL schema in your Supabase project:

# Copy schema.sql to your Supabase project
# Run it in the SQL Editor

The schema creates:

  • accounts table (stores parent PIN hash and biometric settings)
  • profiles table (stores parent and child profiles)
  • RLS policies (ensures users can only access their own data)
  • Realtime subscriptions (syncs profile changes across devices)

Usage

1. Wrap Your App

import { createClient } from "@supabase/supabase-js";
import { SupabaseSyncProvider } from "@familyctx/supabase";
import { FamilyCtxProvider } from "@familyctx/react"; // or @familyctx/expo

const supabase = createClient(
  "https://your-project.supabase.co",
  "your-anon-key"
);

function App() {
  return (
    <SupabaseSyncProvider supabase={supabase}>
      <FamilyCtxProvider>
        <YourApp />
      </FamilyCtxProvider>
    </SupabaseSyncProvider>
  );
}

2. Authentication

import { useSupabaseAuth, useParentAuth } from "@familyctx/supabase";

function LoginScreen() {
  const { login, signUp, loading } = useSupabaseAuth();

  const handleLogin = async () => {
    const result = await login({
      email: "[email protected]",
      password: "password123",
    });

    if (result.success) {
      // Logged in! Account and profiles will auto-sync
    }
  };

  const handleSignUp = async () => {
    const result = await signUp({
      email: "[email protected]",
      password: "password123",
      parentPin: "1234", // 4-digit PIN for parent mode
    });

    if (result.success) {
      // Account created!
    }
  };

  return (
    <View>
      <Button onPress={handleLogin}>Login</Button>
      <Button onPress={handleSignUp}>Sign Up</Button>
    </View>
  );
}

3. Auto-Sync with Realtime

import { useSupabaseSync } from "@familyctx/supabase";

function Dashboard() {
  const { loading, error, synced } = useSupabaseSync();

  if (loading) return <Text>Syncing...</Text>;
  if (error) return <Text>Error: {error.message}</Text>;

  return <YourApp />; // Profiles are synced and will update in real-time
}

4. Parent PIN Verification

import { useParentAuth } from "@familyctx/supabase";
import { useActions } from "@familyctx/react";

function ParentPinScreen({ onClose }) {
  const { verifyParentPin, loading } = useParentAuth();
  const { session } = useActions();
  const [pin, setPin] = useState("");

  const handleSubmit = async () => {
    const result = await verifyParentPin(pin);

    if (result.success) {
      session.confirmParentMode(); // Enable parent mode
      onClose();
    } else {
      alert(result.error); // "Incorrect PIN"
    }
  };

  return (
    <View>
      <TextInput value={pin} onChangeText={setPin} secureTextEntry />
      <Button onPress={handleSubmit}>Verify</Button>
    </View>
  );
}

5. Manual Profile Saves

import { useSupabaseMutations } from "@familyctx/supabase";
import { useActions } from "@familyctx/react";

function AddProfileScreen() {
  const { saveProfile, loading } = useSupabaseMutations();
  const { profile } = useActions();

  const handleSave = async () => {
    const newProfile = {
      id: uuid(),
      accountId: "account-id",
      role: "child",
      name: "Emma",
      createdAt: Date.now(),
    };

    // Add to local store
    profile.add(newProfile);

    // Save to Supabase (syncs to other devices via realtime)
    const result = await saveProfile(newProfile);

    if (result.success) {
      console.log("Profile saved!");
    }
  };

  return <Button onPress={handleSave}>Add Child Profile</Button>;
}

6. Biometric Settings

import { useBiometricSettings } from "@familyctx/supabase";

function SettingsScreen() {
  const { settings, setBiometricEnabled, loadSettings } = useBiometricSettings();

  useEffect(() => {
    loadSettings();
  }, []);

  const handleToggle = async () => {
    const result = await setBiometricEnabled(!settings.enabled);
    if (result.success) {
      console.log("Biometric settings updated!");
    }
  };

  return (
    <Switch
      value={settings.enabled}
      onValueChange={handleToggle}
    />
  );
}

API Reference

Hooks

useSupabaseAuth()

Handles email/password authentication.

  • login({ email, password }) - Sign in
  • signUp({ email, password, parentPin }) - Create account
  • logout() - Sign out
  • loading - Auth loading state
  • error - Auth error

useParentAuth()

Handles parent PIN verification.

  • verifyParentPin(pin) - Verify PIN against DB hash
  • setParentPin(newPin) - Update parent PIN
  • loading - Verification loading state

useSupabaseSync()

Auto-syncs account and profiles on mount + realtime updates.

  • loading - Initial sync loading state
  • error - Sync error
  • synced - True when initial sync complete

useSupabaseMutations()

Manual save operations.

  • saveProfile(profile) - Insert/update profile
  • deleteProfile(profileId) - Delete profile
  • updateBiometricEnabled(enabled) - Toggle biometric setting
  • loading - Mutation loading state

useBiometricSettings()

Manage biometric preferences.

  • settings - { enabled, available }
  • loadSettings() - Fetch from DB
  • setBiometricEnabled(enabled) - Update preference
  • loading - Loading state

Real-time Sync

Profile changes automatically sync across all logged-in devices:

  1. Device A adds a profile → saves to Supabase
  2. Supabase broadcasts change via realtime
  3. Device B receives update → local store updates automatically

No manual refresh needed!

Security

  • RLS policies ensure users can only access their own data
  • Parent PIN is hashed with bcrypt (never stored in plaintext)
  • Biometric preference stored per account

License

MIT