Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Nano Id Laravel Package

snortlin/nano-id

Laravel-friendly NanoID generator for PHP: create short, URL-safe, collision-resistant IDs with configurable length and alphabet. Simple API, lightweight and fast—ideal for public identifiers, tokens, and model keys without exposing sequential IDs.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require snortlin/nano-id
    

    Publish the config (optional):

    php artisan vendor:publish --provider="Snortlin\NanoId\NanoIdServiceProvider" --tag="nano-id-config"
    
  2. First Usage Generate a default ID (21 chars, URL-safe):

    use Snortlin\NanoId\NanoId;
    
    $id = NanoId::generate(); // e.g., "V1StGXvQZ5RgxwKP7Yk3"
    
  3. Laravel Integration Bind to a model trait or service:

    use Snortlin\NanoId\HasNanoId;
    
    class Post extends Model
    {
        use HasNanoId;
    }
    

    Auto-generates nano_id column on create() if configured.


Implementation Patterns

Core Workflows

  1. Basic Generation

    // Default (21 chars)
    $id = NanoId::generate();
    
    // Custom length
    $shortId = NanoId::generate(10); // e.g., "aBc12xYz"
    
  2. Custom Alphabets

    // URL-safe (default)
    $urlSafe = NanoId::generate();
    
    // Custom alphabet (e.g., alphanumeric + symbols)
    $customAlphabet = NanoId::generate(16, '0123456789ABCDEF');
    
  3. Model Integration

    // Auto-generate on create
    class Invoice extends Model
    {
        use HasNanoId;
    
        protected $nanoIdColumn = 'invoice_code';
        protected $nanoIdLength = 12;
    }
    
  4. Batch Generation

    $batch = NanoId::generateBatch(5); // ['id1', 'id2', ...]
    

Advanced Patterns

  • Seeded IDs (for testing/reproducibility):
    $id = NanoId::generate(10, null, 'test-seed');
    
  • Async Generation (in queues/jobs):
    NanoId::generate(); // Thread-safe by design
    
  • Validation:
    use Snortlin\NanoId\NanoIdValidator;
    
    $isValid = NanoIdValidator::validate($id, 21);
    

Integration Tips

  1. Database Schema Use string type with length matching your config (e.g., string(21) for default). Add a unique index for collision safety:

    Schema::table('posts', function (Blueprint $table) {
        $table->string('nano_id', 21)->unique();
    });
    
  2. Migration Hooks Override boot() to auto-generate IDs:

    class Post extends Model
    {
        protected static function boot()
        {
            parent::boot();
            static::creating(function ($model) {
                if (empty($model->nano_id)) {
                    $model->nano_id = NanoId::generate(config('nano-id.length'));
                }
            });
        }
    }
    
  3. API Responses Use the IDs in routes/slugs:

    Route::get('/posts/{nano_id}', [PostController::class, 'show']);
    

Gotchas and Tips

Common Pitfalls

  1. Collision Risk

    • NanoIDs are not cryptographically secure. For critical systems, combine with a DB check:
      do {
          $id = NanoId::generate();
      } while (Model::where('nano_id', $id)->exists());
      
    • Default 21-char IDs have a 1 in 2^128 collision chance.
  2. Alphabet Customization

    • Avoid ambiguous characters (e.g., l1O0) in custom alphabets.
    • Ensure the alphabet is at least 62 chars for reasonable entropy.
  3. Performance

    • Batch generation (generateBatch()) is not parallelized by default. For high throughput, use multiple processes.
    • Avoid regenerating IDs in loops (cache results if possible).
  4. Config Overrides

    • Published config (config/nano-id.php) takes precedence over defaults.
    • Example override:
      'length' => 16,
      'alphabet' => '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
      'seed' => env('NANO_ID_SEED'),
      

Debugging Tips

  1. Validate IDs Use the validator to check malformed IDs:

    NanoIdValidator::validate($id); // Returns bool
    
  2. Log Collisions Add a middleware to log duplicate IDs:

    public function handle($request, Closure $next)
    {
        if (Model::where('nano_id', $request->nano_id)->exists()) {
            Log::warning("NanoID collision detected: {$request->nano_id}");
        }
        return $next($request);
    }
    
  3. Seed Consistency

    • Seeded IDs are deterministic but reduce collision resistance. Use only in tests or controlled environments.

Extension Points

  1. Custom Storage Extend the NanoId facade to persist IDs:

    class CustomNanoId extends NanoId
    {
        public static function generateAndStore()
        {
            $id = parent::generate();
            Model::create(['nano_id' => $id]);
            return $id;
        }
    }
    
  2. Event Triggers Dispatch events on ID generation:

    NanoId::generating(function ($length, $alphabet, $seed) {
        event(new NanoIdGenerating($length, $alphabet, $seed));
    });
    
  3. Fallback for DB Conflicts Implement a retry logic:

    $attempts = 0;
    $maxAttempts = 3;
    do {
        $id = NanoId::generate();
        $attempts++;
    } while ($attempts < $maxAttempts && Model::where('nano_id', $id)->exists());
    

Configuration Quirks

  • Alphabet Length: Must be ≥ 62 for optimal entropy. Shorter alphabets increase collision risk.
  • Seed Length: If provided, must be ≤ 32 chars (truncated otherwise).
  • Thread Safety: The package is thread-safe, but custom alphabets/seeds must be immutable across requests.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
ilhamsyabani/laravel-volt-starter
thethunderturner/filament-latex
ghostcompiler/laravel-querybuilder
webrek/laravel-telescope-mongodb
anousss007/blatui
zatona-eg/zatona-eg-api
cocosmos/filament-sticky-save-bar
patrickbussmann/oauth2-apple
3brs/enterprise-security-bundle
anousss007/vigilance
supportpal/eloquent-model
ardenexal/fhir-models
laravel-at/laravel-image-sanitize
romalytar/yammi-audit-log-laravel
ardenexal/fhir-validation
arshaviras/weather-widget
laravel-chronicle/core
sunchayn/nimbus
daikazu/eloquent-salesforce-objects
unseen-codes/chat