Skip to main content

dart_smb2 0.2.5 copy "dart_smb2: ^0.2.5" to clipboard
dart_smb2: ^0.2.5 copied to clipboard

Dart client for SMB2/3 built on libsmb2. Listings, reads, streaming, atomic downloads, writes and cancellation from worker isolates. Targets macOS, Windows, Linux, iOS and Android.

dart_smb2 #

SMB2/3 client for Dart and Flutter.

logo dart_smb2 is a Dart client for SMB2 and SMB3 file shares, built on libsmb2. It lists, reads, streams, downloads and writes files on Samba, Windows and NAS shares from worker isolates that reconnect on their own.

Installation #

Add dart_smb2 to your pubspec.yaml:

dependencies:
  dart_smb2: ^0.2.4

Platform requirements #

Platform Minimum Architecture Size Device Emulator
Android 7.0 (SDK 24) arm64-v8a, armeabi-v7a, x86_64 246, 233, 253 KB Yes Yes
iOS 13.0 arm64, x86_64 271, 235 KB Yes Yes
macOS 10.15 arm64, x86_64 257, 239 KB Yes -
Windows 10 arm64, x86_64 238, 256 KB Yes -
Linux glibc 2.31 (Ubuntu 20.04, Debian 11) aarch64, x86_64 259, 268 KB Yes -

The package needs Dart 3.10, and Flutter 3.47 in a Flutter app. It is a plain Dart package: command-line tools and servers use it as well.


Features #

Pure Dart
no Flutter plugin: a build hook bundles libsmb2 for Android, iOS, Linux, macOS and Windows, checked against pinned SHA-256s.
Worker isolates
Smb2Pool runs one connection per isolate and sends each call to the least busy one; the UI isolate never waits on the network.
Reconnects
a dropped connection is reconnected once for every caller, the call repeated when that is safe, and open files reopened.
Streaming and downloads
streamFile() reads one chunk ahead; downloadToFile() writes at the disk's pace and renames into place only when complete.
Cancellation
every call on a connected pool but the closing ones takes an Smb2CancelToken, the same as dart_plex's and dart_jellyfin's.
Typed errors
every failure is a Smb2Exception classified from the server's NT status: auth, not found, network, transient, cancelled.
No extra copies
reads land in native buffers that reach your isolate without a copy.
SMB3 security
NTLM sign-in, encryption and signing, and the dialect you choose, up to SMB 3.1.1.
Files and directories
listings with metadata, ranges, handles, writes, renames, timestamps, share space and share enumeration.
Synchronous client
Smb2Client, the client the workers run, for code that manages its own isolates.

Quick start #

import 'package:dart_smb2/dart_smb2.dart';

Future<void> main() async {
  final pool = await Smb2Pool.connect(
    host: '192.168.1.10',
    share: 'Music',
    user: 'alice',
    password: 'secret',
  );
  try {
    // List the share's root.
    for (final entry in await pool.listDirectory('')) {
      print('${entry.name}  ${entry.isDirectory ? 'dir' : '${entry.size} B'}');
    }

    // Read a small file whole.
    final cover = await pool.readFile('Album/cover.jpg');
    print('cover: ${cover.length} bytes');

    // Download a large one to disk.
    final bytes = await pool.downloadToFile(
      'Album/01 - Intro.flac',
      '/tmp/intro.flac',
      onProgress: (received, total) => print('$received / $total'),
    );
    print('downloaded $bytes bytes');
  } on Smb2Exception catch (e) {
    print('SMB error: ${e.type.name}: ${e.message}');
  } finally {
    await pool.disconnect();
  }
}

How it works #

Smb2Pool is the entry point. It runs a few worker isolates, each with its own connection to the share and its own Smb2Client, the synchronous client over libsmb2. Your code calls the pool from any isolate. Each call goes to the least busy worker, and its result comes back without blocking the caller.

Architecture: your code calls Smb2Pool, which sends each request to one of its worker isolates; each worker runs an Smb2Client over a libsmb2 context of its own and holds a connection to the SMB server

Working with the pool #

Connecting #

final pool = await Smb2Pool.connect(
  host: 'nas.local',
  share: 'Private',
  user: 'alice',
  password: 'secret',
  seal: true, // require SMB3 encryption
);

Paths are relative to the share, and '' is its root. See Connection for the options, listing the shares of a server and disconnecting.

Files and directories #

final entries = await pool.listDirectory('Album');
final stat = await pool.stat('Album/01 - Intro.flac');
await pool.mkdir('Backup/2026');
await pool.rename('Backup/log.bin', 'Backup/2026/log.bin');

A listing carries each entry's metadata, so no request per entry is needed. See Files and directories for metadata, share space and the other operations.

Reading, writing and streaming #

final header = await pool.readFileRange('Album/01 - Intro.flac', length: 64 * 1024);
await pool.writeFile('Notes/todo.txt', utf8.encode('buy milk\n'));
await for (final chunk in pool.streamFile('Album/01 - Intro.flac')) {
  print('${chunk.length} bytes');
}

See Reading and writing for handles, withFile, downloads to disk and streamed writes.

Cancellation and errors #

final token = Smb2CancelToken();
try {
  await pool.downloadToFile('Album/01 - Intro.flac', '/tmp/intro.flac', cancelToken: token);
} on Smb2Exception catch (e) {
  if (e.isAuthError) print('ask for the password again');
  if (e.isTransient) print('try again later');
}

A dropped connection is reconnected once for every caller, and the call repeated when that is safe. See Errors and cancellation for every error type and what the pool repeats.

Your own isolates #

Smb2Client is the blocking client the workers run. See Synchronous client to use it from an isolate of your own.


Permissions #

Android #

<uses-permission android:name="android.permission.INTERNET" />

macOS #

Add to DebugProfile.entitlements and Release.entitlements:

<key>com.apple.security.network.client</key>
<true/>

Documentation #


Project background #

I wrote the bindings, the client, the pool and the build hook with Claude Code. The native library is libsmb2 by Ronnie Sahlberg, licensed under the LGPL-2.1: see NOTICE for what an app that bundles it should include.

Samba is a trademark of the Software Freedom Conservancy, and Windows a trademark of Microsoft. dart_smb2 is not affiliated with either.


Developed by Alessandro Di Ronza

8
likes
160
points
7.35k
downloads
screenshot

Documentation

API reference

Publisher

verified publisherales-drnz.com

Weekly Downloads

Dart client for SMB2/3 built on libsmb2. Listings, reads, streaming, atomic downloads, writes and cancellation from worker isolates. Targets macOS, Windows, Linux, iOS and Android.

Repository (GitHub)
View/report issues

Topics

#cross-platform #smb2 #smb3 #samba #libsmb2

License

BSD-3-Clause (license)

Dependencies

code_assets, crypto, ffi, hooks, meta

More

Packages that depend on dart_smb2