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

@pubflow/react

v0.4.3

Published

React adapter for Pubflow framework with support for TanStack Router and SWR - Now with snake_case support

Readme

@pubflow/react

React adapter for the Pubflow framework with support for any React-based framework.

📚 Documentation

Features

  • Complete React integration for Pubflow
  • SWR for data fetching and caching
  • Framework-agnostic design (works with any React framework)
  • Support for Remix, Next.js, Create React App, and more
  • Bridge Payment Client for payment processing (NEW in v0.4.0)
  • Optimized for React 17+
  • TypeScript support
  • Customizable components

Installation

# Install the core package and React adapter
npm install @pubflow/core @pubflow/react

# Install SWR (required)
npm install swr

# Optional: Install Zod for schema validation
npm install zod

Basic Usage

Provider Setup

Wrap your application with the PubflowProvider:

// App.jsx
import React from 'react';
import { PubflowProvider } from '@pubflow/react';

function App() {
  return (
    <PubflowProvider
      config={{
        baseUrl: 'https://api.example.com',
        bridgeBasePath: '/bridge',
        authBasePath: '/auth'
      }}
    >
      <YourApp />
    </PubflowProvider>
  );
}

export default App;

Authentication

Use the useAuth hook to access authentication functionality:

// Login.jsx
import React, { useState } from 'react';
import { useAuth } from '@pubflow/react';

function Login() {
  const { login, isLoading } = useAuth();
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const handleSubmit = async (e) => {
    e.preventDefault();

    try {
      const result = await login({ email, password });

      if (result.success) {
        // Redirect to dashboard
      }
    } catch (error) {
      console.error('Login failed:', error);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="Email"
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        placeholder="Password"
      />
      <button type="submit" disabled={isLoading}>
        {isLoading ? 'Logging in...' : 'Login'}
      </button>
    </form>
  );
}

export default Login;

Data Fetching with SWR

Use the useBridgeQuery hook to fetch data:

// UserList.jsx
import React from 'react';
import { useBridgeApi, useBridgeQuery } from '@pubflow/react';

function UserList() {
  const userService = useBridgeApi({ endpoint: 'users' });
  const { data: users, isLoading, error, refetch } = useBridgeQuery(
    userService,
    'list',
    { limit: 10 }
  );

  if (isLoading) {
    return <div>Loading...</div>;
  }

  if (error) {
    return (
      <div>
        <div>Error: {error.message}</div>
        <button onClick={refetch}>Retry</button>
      </div>
    );
  }

  return (
    <div>
      <h1>Users</h1>
      <ul>
        {users.map(user => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
}

export default UserList;

CRUD Operations

Use the useBridgeCrud hook for complete CRUD operations:

// UserManagement.jsx
import React, { useState } from 'react';
import { useBridgeCrud } from '@pubflow/react';

function UserManagement() {
  const [formData, setFormData] = useState({ name: '', email: '' });

  const {
    items: users,
    createItem,
    updateItem,
    deleteItem,
    loading,
    error
  } = useBridgeCrud({
    entityConfig: {
      endpoint: 'users'
    },
    successMessages: {
      create: 'User created successfully',
      update: 'User updated successfully',
      delete: 'User deleted successfully'
    }
  });

  const handleSubmit = async (e) => {
    e.preventDefault();

    try {
      await createItem(formData);
      setFormData({ name: '', email: '' });
    } catch (error) {
      console.error('Failed to create user:', error);
    }
  };

  return (
    <div>
      <h1>User Management</h1>

      <form onSubmit={handleSubmit}>
        <input
          type="text"
          value={formData.name}
          onChange={(e) => setFormData({ ...formData, name: e.target.value })}
          placeholder="Name"
        />
        <input
          type="email"
          value={formData.email}
          onChange={(e) => setFormData({ ...formData, email: e.target.value })}
          placeholder="Email"
        />
        <button type="submit" disabled={loading}>
          {loading ? 'Creating...' : 'Create User'}
        </button>
      </form>

      {error && <div>Error: {error.message}</div>}

      <ul>
        {users.map(user => (
          <li key={user.id}>
            {user.name} ({user.email})
            <button onClick={() => deleteItem(user.id)}>Delete</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default UserManagement;

Persistent Cache

Pubflow supports persistent caching to improve performance and offline experience:

import { PubflowProvider, createPersistentCache } from '@pubflow/react';

function App() {
  // Create a persistent cache provider
  const persistentCacheProvider = createPersistentCache({
    prefix: 'my_app_cache',
    ttl: 24 * 60 * 60 * 1000, // 24 hours
  });

  return (
    <PubflowProvider
      config={{
        baseUrl: 'https://api.example.com',
        bridgeBasePath: '/bridge',
        authBasePath: '/auth'
      }}
      persistentCache={{
        enabled: true,
        provider: persistentCacheProvider
      }}
    >
      <YourApp />
    </PubflowProvider>
  );
}

For more information, see the Persistent Cache documentation.

BridgeForm Component

Pubflow provides a powerful form component that integrates with Zod schemas and Bridge API:

import { BridgeForm } from '@pubflow/react';
import { z } from 'zod';

// Define schema
const userSchema = z.object({
  name: z.string().min(2, 'Name must be at least 2 characters'),
  email: z.string().email('Invalid email address'),
  role: z.enum(['user', 'admin'], 'Role must be either user or admin')
});

function CreateUser() {
  return (
    <div>
      <h1>Create User</h1>
      <BridgeForm
        schema={userSchema}
        mode="create"
        entityConfig={{ endpoint: 'users' }}
        mainColor="#c30000"
        onSuccess={(data) => {
          console.log('User created:', data);
          // Navigate or show success message
        }}
      />
    </div>
  );
}

For more information, see the BridgeForm documentation.

Schema Validation

Pubflow recommends defining schemas at the application level, not in the adapter:

// lib/schemas/user.js
import { z } from 'zod';

// Schema for complete user entity
export const userSchema = z.object({
  id: z.string().uuid().optional(),
  name: z.string().min(2, 'Name must be at least 2 characters'),
  email: z.string().email('Invalid email address'),
  role: z.enum(['user', 'admin'], 'Role must be either user or admin')
});

// Schema for creating a user
export const createUserSchema = userSchema.omit({
  id: true
});

// Schema for updating a user
export const updateUserSchema = userSchema
  .partial()
  .extend({
    id: z.string().uuid()
  });

// TypeScript types inferred from schemas
export type User = z.infer<typeof userSchema>;
export type CreateUser = z.infer<typeof createUserSchema>;
export type UpdateUser = z.infer<typeof updateUserSchema>;

These schemas can then be used with Pubflow's CRUD operations:

import { useBridgeCrud } from '@pubflow/react';
import { userSchema, createUserSchema, updateUserSchema } from '../lib/schemas/user';

function UsersPage() {
  const {
    items: users,
    createItem,
    updateItem,
    deleteItem,
    validationErrors
  } = useBridgeCrud({
    entityConfig: {
      endpoint: 'users'
    },
    schemas: {
      entity: userSchema,
      create: createUserSchema,
      update: updateUserSchema
    }
  });

  // Component implementation...
}

Framework Integration

Pubflow is designed to work with any React-based framework. Here are examples for popular frameworks:

For detailed Remix integration, see the Remix Integration Guide.

Remix Integration

// app/routes/dashboard.jsx
import { useLoaderData, redirect } from '@remix-run/react';
import { json } from '@remix-run/node';
import { useRequireAuth } from '@pubflow/react';

// Server-side authentication check
export async function loader({ request }) {
  // Get session from cookie
  const cookieHeader = request.headers.get('Cookie');
  const token = parseCookie(cookieHeader)['pubflow_session_token'];

  if (!token) {
    return redirect('/login');
  }

  // You can also fetch initial data here
  return json({ initialData: 'some data' });
}

// Client-side component
export default function Dashboard() {
  const { initialData } = useLoaderData();

  // Client-side authentication check
  useRequireAuth({
    allowedTypes: ['admin', 'user'],
    redirectTo: '/login',
    // Use Remix's navigate function
    redirectFn: (path) => {
      window.location.href = path;
    }
  });

  return (
    <div>
      <h1>Dashboard</h1>
      {/* Dashboard content */}
    </div>
  );
}

Next.js Integration

// pages/dashboard.jsx
import { useRouter } from 'next/router';
import { useRequireAuth } from '@pubflow/react';

export default function Dashboard() {
  const router = useRouter();

  // Client-side authentication check
  useRequireAuth({
    allowedTypes: ['admin', 'user'],
    redirectTo: '/login',
    // Use Next.js router
    redirectFn: (path) => {
      router.push(path);
    }
  });

  return (
    <div>
      <h1>Dashboard</h1>
      {/* Dashboard content */}
    </div>
  );
}

Create React App Integration

// src/pages/Dashboard.jsx
import { useNavigate } from 'react-router-dom';
import { useRequireAuth } from '@pubflow/react';

export default function Dashboard() {
  const navigate = useNavigate();

  // Client-side authentication check
  useRequireAuth({
    allowedTypes: ['admin', 'user'],
    redirectTo: '/login',
    // Use React Router's navigate function
    redirectFn: (path) => {
      navigate(path);
    }
  });

  return (
    <div>
      <h1>Dashboard</h1>
      {/* Dashboard content */}
    </div>
  );
}

Components

BridgeView

The BridgeView component conditionally renders content based on authentication and user type:

import { BridgeView } from '@pubflow/react';

// Basic example
<BridgeView>
  <div>This content is only visible to authenticated users</div>
</BridgeView>

// Only for admins
<BridgeView
  allowedTypes="admin"
  fallback={<div>You don't have permission to view this content</div>}
>
  <div>This content is only visible to admins</div>
</BridgeView>

// Multiple user types
<BridgeView
  allowedTypes={['admin', 'editor']}
  loadingComponent={<div>Loading...</div>}
  onUnauthorized={() => console.log('User not authorized')}
>
  <div>This content is visible to admins and editors</div>
</BridgeView>

BridgeTable

The BridgeTable component displays data in a table with sorting, filtering, and pagination:

import { BridgeTable } from '@pubflow/react';

<BridgeTable
  columns={[
    { key: 'name', header: 'Name', sortable: true },
    { key: 'email', header: 'Email', sortable: true },
    { key: 'role', header: 'Role', sortable: true },
    {
      key: 'createdAt',
      header: 'Created At',
      cell: (item) => new Date(item.createdAt).toLocaleDateString(),
      sortable: true
    }
  ]}
  entityConfig={{
    endpoint: 'users'
  }}
  showSearch={true}
  showPagination={true}
  onRowClick={(user) => console.log('Selected user:', user)}
  actions={(user) => (
    <button onClick={() => handleDelete(user.id)}>Delete</button>
  )}
/>

License

AGPL-3.0-or-later