Generate UUID in Dart
The uuid package on pub.dev is the Dart standard — supports v4, v7, v5, and v1. Works on Flutter, server-side Dart, and web. Uses dart:math Random.secure() for CSPRNG entropy.
Quick Reference
| Method | Version | Sortable | Use Case |
|---|---|---|---|
| uuid.v4() | v4 | No | General purpose — session IDs, record IDs |
| uuid.v7() | v7 | Yes | Database PKs, event logs — time-ordered |
| uuid.v5() | v5 | No | Deterministic — same namespace + name = same UUID |
| Uuid.isValidUUID() | any | — | Validate an existing UUID string |
Primary Implementation
import 'package:uuid/uuid.dart';
void main() {
// Create a Uuid instance once — reuse it
const uuid = Uuid();
// UUID v4 — random, CSPRNG-backed
final id = uuid.v4();
print(id);
// → f47ac10b-58cc-4372-a567-0e02b2c3d479
// UUID v7 — time-ordered (great for database PKs)
final idV7 = uuid.v7();
print(idV7);
// → 018e8f6a-1b2c-7d3e-9f4a-5b6c7d8e9f0a
// UUID v5 — deterministic
final idV5 = uuid.v5(Uuid.NAMESPACE_DNS, 'example.com');
print(idV5); // always the same for same inputs
// Validate a UUID string
final isValid = Uuid.isValidUUID(fromString: id);
print(isValid); // → true
// Generate multiple
final ids = List.generate(5, (_) => uuid.v4());
}
All UUID Versions
UUID v4 — Random (recommended default)
import 'package:uuid/uuid.dart'; const uuid = Uuid(); final id = uuid.v4(); print(id); // → "550e8400-e29b-41d4-a716-446655440000"
UUID v7 — Time-ordered (database PKs)
import 'package:uuid/uuid.dart'; const uuid = Uuid(); // Millisecond-precision timestamp prefix — sorts chronologically final id = uuid.v7(); print(id); // → "018e8f6a-1b2c-7d3e-9f4a-5b6c7d8e9f0a"
UUID v5 — Deterministic / Namespace-based
import 'package:uuid/uuid.dart'; const uuid = Uuid(); // SHA-1 hash of namespace + name — same inputs always produce the same UUID final id = uuid.v5(Uuid.NAMESPACE_DNS, 'example.com'); print(id); // → always "cfbff0d1-9375-5685-968c-48ce8b15ae17"
Real-World Use Cases
1. Dart model class with UUID primary key
import 'package:uuid/uuid.dart';
const _uuid = Uuid();
class Order {
final String id;
final String customerName;
final double total;
final DateTime createdAt;
Order({
String? id,
required this.customerName,
required this.total,
}) : id = id ?? _uuid.v4(),
createdAt = DateTime.now();
Map<String, dynamic> toJson() => {
'id': id,
'customerName': customerName,
'total': total,
'createdAt': createdAt.toIso8601String(),
};
}
2. Shelf server — request tracing middleware
import 'package:shelf/shelf.dart';
import 'package:uuid/uuid.dart';
const _uuid = Uuid();
Middleware requestIdMiddleware() {
return (Handler innerHandler) {
return (Request request) async {
final requestId = _uuid.v4();
final updatedRequest = request.change(
headers: {...request.headers, 'x-request-id': requestId},
);
final response = await innerHandler(updatedRequest);
return response.change(
headers: {...response.headers, 'x-request-id': requestId},
);
};
};
}
3. Idempotent API call with UUID key
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:uuid/uuid.dart';
const _uuid = Uuid();
Future<Map<String, dynamic>> createPayment({
required String customerId,
required int amountCents,
}) async {
final idempotencyKey = _uuid.v4();
final response = await http.post(
Uri.parse('https://api.example.com/payments'),
headers: {
'Content-Type': 'application/json',
'Idempotency-Key': idempotencyKey,
},
body: jsonEncode({'customerId': customerId, 'amount': amountCents}),
);
return jsonDecode(response.body) as Map<String, dynamic>;
}
Common Mistakes
Creating a new Uuid() instance on every call
Instantiate const uuid = Uuid() once at the top level or as a class field. Creating a new instance on every UUID generation is wasteful — the instance is stateless and safe to reuse.
Using Random() instead of Random.secure() for custom entropy
dart:math's Random() is not CSPRNG-backed. If you need custom random bytes, always use Random.secure(). The uuid package handles this correctly internally.
Not validating UUIDs from external sources
UUIDs coming from API responses or user input should be validated with Uuid.isValidUUID(fromString: str) before using them in queries or business logic.
How It Works
The uuid package uses dart:math's Random.secure() for entropy, which maps to the OS CSPRNG on all platforms — /dev/urandom on Linux/macOS, CryptGenRandom on Windows, and the platform CSPRNG on iOS/Android.
The package is pure Dart — no native code, no platform channels. It works identically on Flutter (mobile/web/desktop) and server-side Dart.
Output Formats
uuid.v4()
f47ac10b-58cc-4372-a567-0e02b2c3d479
uuid.v4().replaceAll('-', '')
f47ac10b58cc4372a5670e02b2c3d479
uuid.v4().toUpperCase()
F47AC10B-58CC-4372-A567-0E02B2C3D479
Best Practices
Declare const uuid = Uuid() once at the top level — reuse it everywhere.
Use uuid.v7() for database primary keys — sequential inserts avoid index fragmentation.
Validate incoming UUIDs with Uuid.isValidUUID() at API boundaries.
Performance
Dart generates UUIDs quickly in both JIT (development) and AOT (production) modes. The pure-Dart implementation has no native bridge overhead.
For bulk generation, List.generate(n, (_) => uuid.v4()) is idiomatic and efficient.
Installation
dart pub add uuid
Works on Dart 2.12+ (null safety). Compatible with Flutter, server-side Dart, and Dart web.
Security
Entropy source: dart:math's Random.secure() — maps to the OS CSPRNG on all platforms. Cryptographically secure.
Suitable for session tokens, API keys, and database primary keys. Never use Random() (non-secure) for UUID generation.