webworkerjoshua/laravel-nanoid

A Laravel package for generating and managing Nano ID values.

Maintainers

Package info

github.com/webworkerJoshua/laravel-nanoid

pkg:composer/webworkerjoshua/laravel-nanoid

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-05-11 18:51 UTC

This package is auto-updated.

Last update: 2026-05-11 19:37:13 UTC


README

webworkerJoshua/laravel-nanoid is a Laravel package for generating and assigning Nano ID values.

The generator follows the secure API from Nano ID 5 where it maps cleanly to PHP:

  • secure random bytes from random_bytes()
  • the official URL-friendly urlAlphabet
  • default size of 21 characters
  • custom alphabets with rejection sampling to avoid modulo bias
  • custom random byte generators for tests or advanced integrations

The JavaScript package also ships a non-secure API based on Math.random(). This package intentionally exposes only the secure generator.

References:

Installation

Requirements:

  • PHP 8.2+
  • Laravel 11, 12, or 13
composer require webworkerjoshua/laravel-nanoid

Publish the config when you want to change defaults:

php artisan vendor:publish --tag=nanoid-config

Usage

use WebworkerJoshua\LaravelNanoid\Facades\Nanoid;

$id = Nanoid::generate();
$shortId = Nanoid::generate(10);

The package also provides a helper:

$id = nanoid();

For custom alphabets:

use WebworkerJoshua\LaravelNanoid\Nanoid;

$generator = new Nanoid;
$hex = $generator->customAlphabet('0123456789abcdef', 10);

$id = $hex();
$shortId = $hex(5);

For a custom random byte source:

use WebworkerJoshua\LaravelNanoid\Nanoid;

$generator = new Nanoid;
$custom = $generator->customRandom(
    alphabet: 'abcdef',
    defaultSize: 10,
    random: fn (int $bytes): string => random_bytes($bytes),
);

$id = $custom();

The random callback must accept the requested byte count and return either a binary string or an iterable of integers from 0 to 255.

API Notes

  • Nanoid::generate() and nanoid() generate 21 characters by default.
  • Nanoid::generate(0) returns an empty string.
  • ID sizes must be between 0 and 1024 characters.
  • Custom alphabets must be non-empty and contain 256 symbols or less.
  • customAlphabet($alphabet, $size) returns a callable that also accepts a per-call size override.
  • customRandom($alphabet, $size, $random) follows Nano ID's rejection-sampling algorithm to avoid modulo bias.

Eloquent

Add the HasNanoids trait to a model to fill the configured attribute when the model is created:

use Illuminate\Database\Eloquent\Model;
use WebworkerJoshua\LaravelNanoid\Eloquent\HasNanoids;

class Post extends Model
{
    use HasNanoids;

    protected $fillable = [
        'title',
    ];
}

When the Nano ID attribute is the model key, the trait sets $incrementing = false and $keyType = 'string' during model initialization. Primary keys use a model prefix by default, so a User model receives IDs like user_V1StGXR8_Z5jdHi6B-myT.

Use a string column long enough for the prefix plus the generated ID, and add a unique index for non-primary Nano ID columns:

Schema::create('posts', function (Blueprint $table): void {
    $table->string('id', 64)->primary();
    $table->string('public_id', 64)->unique()->nullable();
    $table->string('title');
    $table->timestamps();
});

Models can override the attribute, size, alphabet, or prefix:

class Post extends Model
{
    use HasNanoids;

    protected $fillable = [
        'title',
    ];

    protected string $nanoidAttribute = 'public_id';

    protected int $nanoidSize = 10;

    protected string $nanoidAlphabet = '0123456789abcdef';

    protected string $nanoidPrefix = 'post_';
}

You can generate Nano IDs for multiple columns and configure each column independently:

class Session extends Model
{
    use HasNanoids;

    protected $fillable = [
        'name',
    ];

    protected array $nanoidAttributes = ['id', 'user_id'];

    protected array $nanoidPrefix = [
        'id' => 'session_',
        'user_id' => 'user_',
    ];

    protected array $nanoidSize = [
        'id' => 21,
        'user_id' => 12,
    ];

    protected array $nanoidAlphabet = [
        'user_id' => '0123456789abcdef',
    ];
}

Each per-column option may also define a '*' fallback key.

Existing attribute values are preserved. The trait does not query the database to retry collisions; enforce uniqueness with primary or unique indexes.

Configuration

return [
    'alphabet' => env('NANOID_ALPHABET', Nanoid::DEFAULT_ALPHABET),
    'size' => (int) env('NANOID_SIZE', Nanoid::DEFAULT_SIZE),
    'prefix' => env('NANOID_PREFIX'),
    'use_model_prefix' => filter_var(env('NANOID_USE_MODEL_PREFIX', true), FILTER_VALIDATE_BOOLEAN),
    'model_attribute' => env('NANOID_MODEL_ATTRIBUTE', 'id'),
];

Use the official collision calculator before reducing size or alphabet length for high-volume IDs.

Available environment variables:

  • NANOID_ALPHABET
  • NANOID_SIZE
  • NANOID_PREFIX
  • NANOID_USE_MODEL_PREFIX
  • NANOID_MODEL_ATTRIBUTE

Testing

composer test
composer larastan
composer format