Launch Week Day 2: Introducing Reports: An Extensible Reporting Framework for Socket Data.Learn More
Socket
Book a DemoSign in
Socket

frappe-sdk-react-i4z

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

frappe-sdk-react-i4z

React hooks library for Frappe Framework

latest
Source
npmnpm
Version
1.0.0
Version published
Maintainers
1
Created
Source

My Frappe SDK React

A React hooks library for Frappe Framework that provides a simple and intuitive way to interact with Frappe backends.

Features

  • 🔐 Authentication: Login/logout with username/password and token-based authentication
  • 🗄️ Database Operations: Full CRUD operations with hooks for documents
  • 📄 File Upload: Upload files with progress tracking
  • 🤙 API Calls: Make calls to whitelisted backend functions
  • 🔍 Search: Search documents with debouncing
  • Real-time: Built on SWR for automatic data revalidation and caching
  • 📘 TypeScript: Full TypeScript support with type safety

Installation

npm install my-frappe-sdk-react

Quick Start

1. Setup Provider

Wrap your app with the FrappeProvider:

import { FrappeProvider } from 'my-frappe-sdk-react'

function App() {
  return (
    <FrappeProvider url="https://your-frappe-site.com">
      <YourAppComponents />
    </FrappeProvider>
  )
}

2. Authentication

import { useFrappeAuth } from 'my-frappe-sdk-react'

function LoginComponent() {
  const { login, logout, currentUser, isLoggedIn } = useFrappeAuth()

  const handleLogin = async () => {
    try {
      await login('username', 'password')
    } catch (error) {
      console.error('Login failed:', error)
    }
  }

  if (isLoggedIn) {
    return (
      <div>
        <p>Welcome, {currentUser?.full_name}!</p>
        <button onClick={logout}>Logout</button>
      </div>
    )
  }

  return <button onClick={handleLogin}>Login</button>
}

3. Fetch Documents

import { useFrappeGetDoc, useFrappeGetDocList } from 'my-frappe-sdk-react'

function DocumentsList() {
  // Fetch a single document
  const { data: user, error, isLoading } = useFrappeGetDoc('User', 'john@example.com')

  // Fetch list of documents
  const { data: todos } = useFrappeGetDocList({
    doctype: 'ToDo',
    fields: ['name', 'description', 'status'],
    filters: { status: 'Open' },
    limit_page_length: 10
  })

  if (isLoading) return <div>Loading...</div>
  if (error) return <div>Error: {error.message}</div>

  return (
    <div>
      <h2>User: {user?.full_name}</h2>
      <h3>Open Todos:</h3>
      {todos.map(todo => (
        <div key={todo.name}>{todo.description}</div>
      ))}
    </div>
  )
}

4. Create/Update Documents

import { useFrappeCreateDoc, useFrappeUpdateDoc } from 'my-frappe-sdk-react'

function TodoManager() {
  const { createDoc, loading: creating } = useFrappeCreateDoc('ToDo')
  const { updateDoc, loading: updating } = useFrappeUpdateDoc('ToDo')

  const handleCreate = async () => {
    try {
      const newTodo = await createDoc({
        description: 'New todo item',
        status: 'Open'
      })
      console.log('Created:', newTodo)
    } catch (error) {
      console.error('Create failed:', error)
    }
  }

  const handleUpdate = async (name: string) => {
    try {
      const updatedTodo = await updateDoc(name, {
        status: 'Closed'
      })
      console.log('Updated:', updatedTodo)
    } catch (error) {
      console.error('Update failed:', error)
    }
  }

  return (
    <div>
      <button onClick={handleCreate} disabled={creating}>
        {creating ? 'Creating...' : 'Create Todo'}
      </button>
    </div>
  )
}

5. File Upload

import { useFrappeFileUpload } from 'my-frappe-sdk-react'

function FileUploader() {
  const { upload, loading, progress, error } = useFrappeFileUpload()

  const handleFileUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0]
    if (!file) return

    try {
      const response = await upload(file, {
        is_private: false,
        doctype: 'File',
        fieldname: 'file_url'
      })
      console.log('Uploaded:', response.message.file_url)
    } catch (error) {
      console.error('Upload failed:', error)
    }
  }

  return (
    <div>
      <input type="file" onChange={handleFileUpload} disabled={loading} />
      {loading && (
        <div>
          Uploading... {progress?.percentage}%
        </div>
      )}
      {error && <div>Error: {error.message}</div>}
    </div>
  )
}

6. API Calls

import { useFrappeCall } from 'my-frappe-sdk-react'

function CustomAPICall() {
  const { call, data, loading, error } = useFrappeCall()

  const handleAPICall = async () => {
    try {
      const result = await call({
        method: 'your_app.api.custom_method',
        args: {
          param1: 'value1',
          param2: 'value2'
        }
      })
      console.log('Result:', result)
    } catch (error) {
      console.error('API call failed:', error)
    }
  }

  return (
    <div>
      <button onClick={handleAPICall} disabled={loading}>
        {loading ? 'Calling...' : 'Call API'}
      </button>
      {data && <pre>{JSON.stringify(data, null, 2)}</pre>}
      {error && <div>Error: {error.message}</div>}
    </div>
  )
}
import { useFrappeSearch } from 'my-frappe-sdk-react'

function UserSearch() {
  const { search, data, loading } = useFrappeSearch('User', {}, 300)

  return (
    <div>
      <input
        type="text"
        placeholder="Search users..."
        onChange={(e) => search(e.target.value)}
      />
      {loading && <div>Searching...</div>}
      {data.map(user => (
        <div key={user.value}>{user.label}</div>
      ))}
    </div>
  )
}

Configuration

Token-based Authentication

<FrappeProvider
  config={{
    url: 'https://your-frappe-site.com',
    useToken: true,
    tokenParams: {
      type: 'token',
      token: 'your-api-token'
    }
  }}
>
  <App />
</FrappeProvider>

Available Hooks

HookDescription
useFrappeAuthAuthentication methods and user state
useFrappeGetDocFetch a single document
useFrappeGetDocListFetch list of documents with filters
useFrappeGetDocCountGet document count with filters
useFrappeCreateDocCreate new documents
useFrappeUpdateDocUpdate existing documents
useFrappeDeleteDocDelete documents
useFrappeCallMake API calls to backend methods
useFrappeFileUploadUpload files with progress tracking
useFrappeSearchSearch documents with debouncing

TypeScript Support

All hooks are fully typed. You can provide generic types for better type safety:

interface CustomToDo {
  name: string
  description: string
  status: 'Open' | 'Closed'
  priority: number
}

const { data: todos } = useFrappeGetDocList<CustomToDo>({
  doctype: 'ToDo',
  fields: ['name', 'description', 'status', 'priority']
})

// todos is now typed as CustomToDo[]

Error Handling

All hooks provide error states and throw detailed error objects:

const { data, error, isLoading } = useFrappeGetDoc('User', 'invalid-user')

if (error) {
  console.log(error.message) // User-friendly error message
  console.log(error.exception) // Technical details
  console.log(error.exc_type) // Exception type
}

License

MIT

Keywords

frappe

FAQs

Package last updated on 09 Sep 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts