SmbTask per operation
Every call returns a task — await .result(), watch with .subscribe(), or abort with .cancel(). Mix all three freely.
@cetapod/react-native-smb
Connect to NAS, file servers, and Windows shares from your mobile app. Powered by libsmb2 and Nitro Modules — with a task-first API built for real transfers.
npm install @cetapod/react-native-smb react-native-nitro-modules
Not a thin wrapper — a full SMB client with connection pooling, pipelined transfers, and a task model designed for mobile UX.
Every call returns a task — await .result(), watch with .subscribe(), or abort with .cancel(). Mix all three freely.
Up to four parallel SMB sessions. Slot 0 is reserved for interactive ops — list, rename, move — so UI never blocks behind bulk transfers.
interactive-priority slot 0Within each transfer, up to eight SMB2 READ/WRITE requests in flight on the same connection. Credit-based pipelining for maximum throughput.
kMaxInFlight = 8useSubscribe mirrors task subscriptions. useTransfers powers a transfer tray — track every download and upload in your UI.
SmbError and SmbTaskError with structured codes. Know exactly why a connection failed or a transfer was interrupted.
Battle-tested C SMB stack exposed through Nitro's JSI bridge. Static types from TypeScript to C++ — no bridge serialization overhead.
native performanceWhether you're building a consumer NAS app or an enterprise file tool, the task-first API and connection pool keep UI responsive during heavy I/O.
Browse shares, preview files, and manage folders on Synology, QNAP, Windows, or Samba — with list and metadata ops prioritized on slot 0.
Stream or download large assets from network shares. Pipelined transfers and useTransfers give you tray UI with live progress and cancel.
Authenticate with domain credentials, read ACLs via getSecurityDescriptor, and integrate with existing SMB infrastructure on iOS.
Upload and download in parallel across pool slots. Batch deletes with SmbTask.settleAll and deterministic error handling per file.
Parallelism at two levels — across tasks via the pool, within transfers via chunk pipelining.
Slot 0 accepts only interactive operators — shallow list, path info, rename, move. Bulk metadata work uses slots 1–3. When slot 0 is busy, interactive ops overflow to general slots rather than queuing behind downloads.
Each pool slot is a full smb2_context with its own TCP socket. The server sees N separate client connections. Application-level scheduling on top of what libsmb2 provides.
getPoolInfo() and subscribePoolInfo() expose slot state, task IDs, and operator kinds. The example app includes a PoolDebugPanel for real-time inspection.
Install, connect to a share, list files, download with progress.
import { SMB, SmbCredentials } from '@cetapod/react-native-smb'; const smb = SMB(); const creds: SmbCredentials = { username: 'user', password: 'pass', }; await smb.connect('smb://192.168.1.100/Media', creds).result(); const entries = await smb.listDirectory('/', false).result(); const task = smb.downloadFile('/video.mp4', '/local/video.mp4'); task.subscribe((snap) => console.log(snap.progress)); await task.result();
const task = smb.downloadFile(remote, local); // Live getters after subscribe() const unsub = task.subscribe((snap) => { console.log( snap.progress, snap.bytesPerSecond, snap.status, ); }); // Or subscribe without callback — read task.progress task.subscribe(); console.log(task.progress, task.status); // User aborts task.cancel(); unsub();
import { useTransfers, useTransferActions, useSubscribe, } from '@cetapod/react-native-smb'; function TransferTray() { const transfers = useTransfers(); const { cancel, clear } = useTransferActions(); return transfers.map((t) => ( <Row key={t.id} progress={t.progress} /> )); } function TaskBar({ task }) { const { progress } = useSubscribe(task); return <Bar value={progress} />; }
import { SmbTask } from '@cetapod/react-native-smb'; // Delete multiple files — collect all outcomes const tasks = files.map((f) => smb.deleteItem(f.path) ); const results = await SmbTask.settleAll(tasks); // Like Promise.allSettled over .result() for (const r of results) { if (r.status === 'fulfilled') { console.log('deleted', r.value); } }
Deep dives into the task model, API surface, and connection pool internals.
Install, quick start, URL format, and compatibility requirements.
Subscribe, fire-and-forget, transfer tray, error handling patterns.
Every method with signature, parameters, and copy-paste examples.
Interfaces, enums, and classes — full field tables with values.
Slots, acquire modes, chunk pipeline, multichannel comparison.
Expo dev-client demo — login, file browser, transfer tray, pool debug.
Works with modern React Native and Nitro Modules.
| Platform / dependency | Version | Status |
|---|---|---|
| React Native | >= 0.76 | Supported |
| React | >= 19 | Supported |
| react-native-nitro-modules | >= 0.22, < 1.0 | Required |
| iOS | 12+ | Supported |
| Android | — | Coming soon |
| SMB protocol | v2 / v3 | Supported |
Install from npm, run the example app, and start building NAS-aware mobile experiences today.