0%
balqalam Logo
balqalam
FeaturesCommunityPricingDocumentation
Login
  • Introduction
  • Pitch
  • Hogwarts
  • Live Demo
  • MVP
  • Roadmap
  • Launch Sprint
  • PRD
  • Get Started
  • Localhost
  • Architecture
  • Structure
  • Pattern
  • Page
  • Layout
  • Content
  • Types
  • Config
  • Actions
  • Queries
  • Authorization
  • Validation
  • Form
  • Table
  • Detail
  • Card
  • Util
  • Hooks
  • List Params
  • Views
  • README.md
  • ISSUE.md
  • Technology Stack
  • Database
  • File
  • CDN Assets
  • Entry Points
  • Dashboard
  • Authentication
  • Credentials
  • OAuth
  • Flow Diagrams
  • Multi-Tenancy
  • Offline
  • Onboarding
  • Onboarding Videos
  • Add Values
  • Admission
  • Application
  • Attendance
  • Compliance
  • Profile
  • Exams
  • Exam Wizard
  • Timetable
  • Classrooms
  • Notifications
  • Conference
  • LMS (Lumos)
Finance
  • Finance
  • Fee Management
  • Invoice
  • Wallet
  • Salary
  • Payroll
  • Timesheet
  • Expenses
  • Budget
  • Receipt
  • Accounts
  • Banking
  • Reports
  • Dashboard
  • Permissions
  • Messages
  • Integration Flow
  • Provision
  • AI Document Processing
  • Document Intelligence
  • Internationalization
  • Translation
  • Translation Guide
  • Icons
  • Docs Factory
  • Inspiration
  • Listings
  • Teachers
  • Students
  • Catalog
  • Library
  • Contributing
  • Code of conduct
  • GitHub Workflow
  • Database Seeds
  • Database Safety
  • Test Accounts
  • Playwright
  • Prettier
  • Block Rebound
Sales & GTM
  • Marketing Brief
  • Sales
  • Go-to-market
  • Marketing
  • Admission — Feature Spotlight
  • Pilot Program
  • Leads
  • Proposal
  • Outreach Templates
  • Case Study
  • Competitors
  • Landing-page teardown
  • Competitor FAQ
  • Business model
  • Shared economy
  • Traction
Fundraising & Ecosystem
  • Get Support
  • Investor Deck
  • Data Room
  • Investors
  • Accelerators
  • Incubators
  • Grants
  • Sponsors
  • Partners
  • Competitions & Hackathons
  • Universities & Training Centers

Hooks

PreviousNext

Custom hooks colocated next to the feature that owns them.

Custom hooks live next to the feature they serve. Cross-feature hooks live in src/lib/hooks/. Naming is use-<concept>.ts, kebab-case.

Categories

CategoryPurposeReference
Form / stateMulti-step orchestration, draft persistenceform/use-form.ts
Data fetchingServer-action wrappers with loading + erroruse-domains.ts
File operationsUpload progress, drag-and-dropfile/use-upload.ts
Real-timeSocket.IO subscriptions, polling fallbacknotifications/use-notifications.ts
URL statenuqs wrappers for typed search paramslistings/students/use-students.ts
WizardStep state, validation contextwizard/use-wizard.ts
Layout / responsiveMedia query, mobile detect, scroll locksrc/lib/hooks/use-media-query.ts
PermissionsReactive RBAC checks against the sessionauth/use-permissions.ts
Drag and dropDnD-kit wrapperstimetable/use-dnd.ts
TablesSorting, pagination wrappers around TanStacktable/use-table.ts
AnimationsFramer Motion presetsatom/use-scroll-animation.ts
Browser APIsClipboard, localStorage, intersection observersrc/lib/hooks/use-clipboard.ts

Rules

#Rule
1"use client" at the top — hooks always run client-side
2Named exports only
3Return an object, not a tuple — { value, set, isLoading }
4Stay under ~150 lines — a 523-line file with 5 hooks should be 5 files
5Lift duplicates to src/lib/hooks/ when used in 3+ places

Canonical example

"use client"
 
import { useState, useTransition } from "react"
 
import { deleteSubject } from "./actions"
 
export function useSubjectActions() {
  const [pending, startTransition] = useTransition()
  const [error, setError] = useState<string | null>(null)
 
  function remove(id: string, onSuccess?: () => void) {
    startTransition(async () => {
      const res = await deleteSubject({ id })
      if (res.success) {
        onSuccess?.()
      } else {
        setError(res.errorCode)
      }
    })
  }
 
  return { remove, pending, error }
}

Shared hooks already lifted

These live in src/lib/hooks/ — don't reinvent.

HookPurpose
use-media-queryReactive matchMedia
use-mobileMobile breakpoint detection
use-callback-refStable callback ref
use-lock-bodyScroll lock for modals
use-debounced-callbackDebounce a callback
use-clipboardCopy / read clipboard
use-local-storageReactive localStorage state
use-intersection-observerVisibility detection

Anti-patterns

  • use-media-query duplicated 5 times, use-callback-ref 3×, use-mobile 3× — lift to src/lib/hooks/.
  • Multi-hook files — form/use-form.ts is 523 lines exporting 5 hooks. Split.
  • Returning tuples ([value, setValue, loading]) — switch to objects.
  • Side effects in render — wrap in useEffect or useTransition.
  • Reading window without an SSR guard — use typeof window !== "undefined" or useSyncExternalStore.

Naming

  • File: use-<concept>.ts (kebab-case).
  • Function: use<Concept> (camelCase, use prefix).
  • Cross-feature: src/lib/hooks/use-<concept>.ts.
  • Single-purpose — resist exporting 5 hooks per file.

Sibling roles

  • Hooks consume server actions from actions.ts.
  • Hooks don't import db directly — server-only.
  • Hooks export to client.tsx, form.tsx, table.tsx. Server components don't use them.

See also

  • Pattern
  • Actions
  • Util
  • Content
UtilList Params

On This Page

CategoriesRulesCanonical exampleShared hooks already liftedAnti-patternsNamingSibling rolesSee also

Built by Databayt ·

Welcome to balqalam.

A great journey is about to begin.