Skip to main content

Searching...

Tools
Articles
View All Results

Developer Lab · Dart

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

Production Ready
dart
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)

dart
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)

dart
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

dart
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

dart
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

dart
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

dart
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, Performance, and Security

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.

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.

Installation

UUID v4 (uuid package)

bash
dart pub add uuid

Works on Dart 2.12+ (null safety). Compatible with Flutter, server-side Dart, and Dart web.

Frequently Asked Questions

How do I generate a UUID in Dart?

The uuid package on pub.dev is the standard choice for Dart and Flutter. Add uuid to pubspec.yaml, create const uuid = Uuid(), and call uuid.v4() for a random UUID or uuid.v7() for a time-ordered one. It uses a cryptographically secure RNG by default.

Is Uuid().v4() cryptographically secure?

Yes. Uuid().v4() uses the platform CSPRNG (operating system secure random source), suitable for session tokens, API keys, and idempotency keys. Do not use non-cryptographic random sources for security-sensitive identifiers.

What is the difference between UUID v4 and v7 in Dart?

UUID v4 (Uuid().v4() or equivalent) is fully random and not sortable. UUID v7 embeds a millisecond timestamp for chronological sorting (RFC 9562). Use v4 for general-purpose IDs; use v7 for database primary keys at scale.

Do I need to install a package for UUID generation in Dart?

A package or library install may be required. See the Installation section for the recommended approach in Dart.

How do I validate a UUID string in Dart?

Use the platform's UUID parse/validation function, or test against the RFC 4122 regex: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i. Always validate external input at API boundaries.

Should I use UUIDs as database primary keys in Dart applications?

UUIDs work well as primary keys for distributed systems. Prefer native UUID/BINARY(16) column types over VARCHAR(36). For very large tables, consider UUID v7 for better B-tree insert locality.

Can I generate UUIDs in Dart without a network connection?

Yes. UUID generation uses local OS entropy sources and does not require network access. Each call is independent and thread-safe on modern platforms.

What output formats are available in Dart?

The standard hyphenated lowercase string (36 chars) is the default. Most APIs also support 32-char hex (no hyphens) and 16-byte binary formats. Use string format for APIs and binary for database storage.

What RFC standards apply to Dart UUID generation?

Version 4 UUIDs follow RFC 4122. UUID v7 follows RFC 9562 (May 2024). Ensure your chosen method produces compliant version and variant bits.

When should I avoid UUID v1?

Avoid UUID v1 in security-sensitive contexts - it embeds MAC address and timestamp information. Prefer v4 (Uuid().v4() or equivalent) unless you need legacy Cassandra timeuuid compatibility.

Key definitions

UUID
128-bit universally unique identifier, usually shown as 36 hex characters with hyphens.
CSPRNG
Cryptographically secure pseudo-random number generator - the entropy source behind secure UUID generation.
RFC 4122
IETF standard defining UUID versions 1 through 5. Version 4 is random.
RFC 9562
IETF standard adding UUID versions 6, 7, and 8. Version 7 is time-ordered.