NearProvider. They will throw an error if used outside the provider context.
Read Hooks
These hooks fetch data from the blockchain. They all return a consistent shape:interface ViewResult<T> {
data: T | undefined // The fetched data
error: Error | undefined // Any error that occurred
isLoading: boolean // Whether fetch is in progress
refetch: () => Promise<void> // Manually trigger a refetch
}
useView
UseViewParams
required
Call any view method on a NEAR smart contract.
Show UseViewParams Properties
Show UseViewParams Properties
import { useView } from "@near-kit/react"
function Messages() {
const { data, isLoading, error, refetch } = useView<{ limit: number }, Message[]>({
contractId: "guestbook.near",
method: "get_messages",
args: { limit: 10 },
})
if (isLoading) return <p>Loading...</p>
if (error) return <p>Error: {error.message}</p>
return (
<div>
{data?.map((msg) => <p key={msg.id}>{msg.text}</p>)}
<button onClick={refetch}>Refresh</button>
</div>
)
}
function UserProfile({ userId }: { userId?: string }) {
// Only fetch when we have a userId
const { data: profile } = useView({
contractId: "profiles.near",
method: "get_profile",
args: { user_id: userId },
enabled: !!userId, // Won't fetch until userId is truthy
})
if (!userId) return <p>Select a user</p>
return <p>{profile?.name}</p>
}
interface GetMessagesArgs {
limit: number
offset?: number
}
interface Message {
id: string
sender: string
text: string
timestamp: number
}
// Full type safety for args and return type
const { data } = useView<GetMessagesArgs, Message[]>({
contractId: "guestbook.near",
method: "get_messages",
args: { limit: 20, offset: 0 },
})
When
args change (by reference or value), the hook automatically refetches. Use useMemo for computed args to prevent unnecessary refetches.useBalance
UseBalanceParams
required
Fetch an account’s NEAR balance as a formatted string.
Show UseBalanceParams Properties
Show UseBalanceParams Properties
import { useBalance } from "@near-kit/react"
function WalletBalance({ accountId }: { accountId: string }) {
const { data: balance, isLoading, refetch } = useBalance({ accountId })
if (isLoading) return <span>...</span>
return (
<div>
<span>{balance}</span> {/* "10.50 NEAR" */}
<button onClick={refetch}>↻</button>
</div>
)
}
Returns a human-readable string like
"10.50 NEAR". For raw BigInt values, use useNear() and call near.getAccountDetails() directly.useAccountExists
UseAccountExistsParams
required
Check if a NEAR account exists on the network.
Show UseAccountExistsParams Properties
Show UseAccountExistsParams Properties
import { useAccountExists } from "@near-kit/react"
function AccountChecker() {
const [input, setInput] = useState("")
const { data: exists, isLoading } = useAccountExists({
accountId: input,
enabled: input.length > 0,
})
return (
<div>
<input value={input} onChange={(e) => setInput(e.target.value)} />
{isLoading && <span>Checking...</span>}
{exists === true && <span>✓ Account exists</span>}
{exists === false && <span>✗ Account not found</span>}
</div>
)
}
useAccount
Get the current connected account state from the Near client.
interface AccountState {
accountId: string | undefined // The connected account ID
isConnected: boolean // Whether any account is connected
isLoading: boolean // Whether state is being fetched
refetch: () => Promise<void> // Refresh account state
}
import { useAccount } from "@near-kit/react"
function Header() {
const { accountId, isConnected, isLoading } = useAccount()
if (isLoading) return <span>Loading...</span>
if (!isConnected) return <button>Connect Wallet</button>
return <span>Connected: {accountId}</span>
}
This hook accesses internal Near client state. The account is derived from whatever signer was configured (wallet adapter, private key, or keystore).
Mutation Hooks
These hooks modify blockchain state. They return a consistent shape:interface MutationResult<TArgs, TResult> {
mutate: (args: TArgs) => Promise<TResult> // Execute the mutation
data: TResult | undefined // Last successful result
error: Error | undefined // Any error from last call
isPending: boolean // Whether mutation is in progress
isSuccess: boolean // Whether last call succeeded
isError: boolean // Whether last call failed
reset: () => void // Reset mutation state
}
useCall
UseCallParams
required
Call a change method on a NEAR smart contract.
Cache invalidation not included. After a mutation, related queries won’t automatically refetch. For apps where mutations should update the UI, use React Query with
invalidateQueries() instead.Show UseCallParams Properties
Show UseCallParams Properties
import { useCall } from "@near-kit/react"
function IncrementButton() {
const { mutate, isPending, isError, error } = useCall({
contractId: "counter.testnet",
method: "increment",
})
return (
<div>
<button onClick={() => mutate({})} disabled={isPending}>
{isPending ? "Processing..." : "Increment"}
</button>
{isError && <p>Error: {error?.message}</p>}
</div>
)
}
interface AddMessageArgs {
text: string
}
function AddMessage() {
const { mutate, isPending, isSuccess, reset } = useCall<AddMessageArgs, void>({
contractId: "guestbook.near",
method: "add_message",
options: {
gas: "30 Tgas",
attachedDeposit: "0.01 NEAR", // Storage deposit
},
})
const handleSubmit = async (e: FormEvent) => {
e.preventDefault()
const formData = new FormData(e.target as HTMLFormElement)
await mutate({ text: formData.get("text") as string })
}
if (isSuccess) {
return (
<div>
<p>Message sent!</p>
<button onClick={reset}>Send another</button>
</div>
)
}
return (
<form onSubmit={handleSubmit}>
<input name="text" placeholder="Your message" />
<button type="submit" disabled={isPending}>
{isPending ? "Sending..." : "Send"}
</button>
</form>
)
}
const { mutate } = useCall({
contractId: "nft.near",
method: "nft_mint",
options: { gas: "50 Tgas" },
})
// Override deposit for this specific call
await mutate(
{ token_id: "1", receiver_id: "alice.near" },
{ attachedDeposit: "0.1 NEAR" }
)
CallOptions Reference
CallOptions Reference
| Option | Type | Description |
|---|---|---|
gas | string | Gas limit (e.g., "30 Tgas", "100 Tgas") |
attachedDeposit | string | NEAR to attach (e.g., "1 NEAR", "0.01 NEAR") |
waitUntil | "INCLUDED" | "EXECUTED" | "FINAL" | When to resolve the promise |
useSend
Send NEAR tokens to another account.
mutate function with signature:
mutate: (to: string, amount: AmountInput) => Promise<void>
AmountInput is "10 NEAR" | "1000 yocto" | bigint
import { useSend } from "@near-kit/react"
function SendForm() {
const { mutate: send, isPending, isSuccess, error } = useSend()
const [recipient, setRecipient] = useState("")
const [amount, setAmount] = useState("")
const handleSend = async () => {
try {
await send(recipient, `${amount} NEAR`)
} catch (err) {
// Error is also available via `error` state
console.error("Transfer failed:", err)
}
}
return (
<div>
<input
placeholder="Recipient (e.g., bob.near)"
value={recipient}
onChange={(e) => setRecipient(e.target.value)}
/>
<input
placeholder="Amount in NEAR"
value={amount}
onChange={(e) => setAmount(e.target.value)}
/>
<button onClick={handleSend} disabled={isPending}>
{isPending ? "Sending..." : "Send NEAR"}
</button>
{isSuccess && <p>Transfer complete!</p>}
{error && <p>Error: {error.message}</p>}
</div>
)
}
Utility Hooks
useNear
Access the raw Near client instance for advanced operations:import { useNear } from "@near-kit/react"
function AdvancedTransaction() {
const near = useNear()
const handleBatch = async () => {
// Full access to the transaction builder
await near
.transaction("alice.near")
.createAccount("sub.alice.near")
.transfer("sub.alice.near", "5 NEAR")
.addKey("sub.alice.near", "ed25519:...")
.send()
}
return <button onClick={handleBatch}>Create Subaccount</button>
}
useContract
string
required
Get a fully-typed contract interface using
near.contract<T>().import { useContract } from "@near-kit/react"
import type { Contract } from "near-kit"
// Define your contract's type signature
type FungibleToken = Contract<{
view: {
ft_balance_of: (args: { account_id: string }) => Promise<string>
ft_metadata: () => Promise<{ name: string; symbol: string; decimals: number }>
}
call: {
ft_transfer: (args: { receiver_id: string; amount: string }) => Promise<void>
}
}>
function TokenBalance({ accountId }: { accountId: string }) {
const token = useContract<FungibleToken>("usdt.tether-token.near")
const [balance, setBalance] = useState<string>()
useEffect(() => {
token.view.ft_balance_of({ account_id: accountId }).then(setBalance)
}, [token, accountId])
return <p>Balance: {balance}</p>
}
For reactive data fetching with contracts, combine
useContract with useEffect or integrate with React Query. See Data Fetching for patterns.