A Swift implementation of NanoID — a tiny, secure, URL-safe unique string ID generator.
NanoID generates cryptographically secure, URL-safe unique identifiers with a configurable
alphabet and length. It is a Swift port of the official
ai/nanoid JavaScript library, providing identical behavior
including support for zero-length IDs.
The default configuration produces 21-character IDs from a 64-character alphabet — compact enough for URLs, unique enough for distributed systems.
The package ships two libraries:
NanoID— the coreNanoIDtype andNanoIDGenerator, with no external dependencies.NanoIDDependency— optional integration with swift-dependencies by Point-Free, exposingNanoIDGeneratoras a controllable dependency via@Dependency(\.nanoID).
Call NanoID() for a default 21-character, URL-safe ID:
let id = NanoID()
print(id) // e.g. "V1StGXR8_Z5jdHi6B-myT"Customize the alphabet and size using a predefined preset or compose your own:
let hexID = NanoID(from: .hexadecimalLowercase, size: 16)
let shortID = NanoID(from: .alphanumeric, size: 10)
let customID = NanoID(from: .numbers + "-", size: 12)Add @Dependency(\.nanoID) to any feature model to gain controllable NanoID generation:
import Dependencies
import NanoIDDependency
final class ItemsModel {
@Dependency(\.nanoID) var nanoID
var items: [Item] = []
func addButtonTapped() {
items.append(Item(id: nanoID()))
}
}Because NanoID is configurable (alphabet, size), there is no built-in live value.
Register a generator in your app's composition root:
let model = withDependencies {
$0.nanoID = NanoIDGenerator { NanoID() }
} operation: {
ItemsModel()
}Override the dependency in tests for predictable, reproducible output:
@Test
func addItem() {
let model = withDependencies {
$0.nanoID = .incrementing(size: 21)
} operation: {
ItemsModel()
}
model.addButtonTapped()
#expect(model.items == [Item(id: NanoID(rawValue: "000000000000000000000")!)])
}If your app generates IDs for multiple, distinct purposes (e.g. user IDs, session tokens,
log filenames), consider pairing swift-nanoid with
IDGenerator. IDGenerator provides
a keyed registry that lets each component declare exactly the generator it needs, keeping
different ID schemes isolated and independently controllable in tests.
Note: When using
IDGenerator, you only need the coreNanoIDlibrary —NanoIDDependencyis not required, asIDGeneratorprovides its own dependency integration.
extension GeneratorKey where Value == NanoIDGenerator {
static let userID = Self("userID")
static let sessionToken = Self("sessionToken")
}
extension IDGeneratorValues {
var userID: NanoIDGenerator {
get { self[.userID] }
set { self[.userID] = newValue }
}
var sessionToken: NanoIDGenerator {
get { self[.sessionToken] }
set { self[.sessionToken] = newValue }
}
}Each component then declares only what it needs:
struct UserRepository {
@Dependency(\.idGenerators.userID) var userID
}
struct AuthService {
@Dependency(\.idGenerators.sessionToken) var sessionToken
}Add swift-nanoid to your Package.swift:
dependencies: [
.package(url: "https://github.com/ShivaHuang/swift-nanoid", from: "0.1.0"),
],Then add the product you need to your target:
NanoID— core type and generator, no external dependencies.NanoIDDependency— includesNanoIDand integrates with swift-dependencies.
.target(
name: "MyApp",
dependencies: [
// Core only:
.product(name: "NanoID", package: "swift-nanoid"),
// Or with swift-dependencies integration:
.product(name: "NanoIDDependency", package: "swift-nanoid"),
]
),Run locally with swift package --package-path Benchmarks benchmark. Results shown below are from the latest commit on master.
Results from an Apple M2 Pro Mac mini (10-core ARM64, 32 GB).
| Benchmark | Median (p50) | Throughput |
|---|---|---|
nanoid |
3,793 ns | ~264K IDs/s |
customAlphabet |
3,625 ns | ~276K IDs/s |
There are other Swift implementations of NanoID in the community:
The NanoIDDependency module is designed to work with
swift-dependencies by
Point-Free. Their library provides the dependency management
infrastructure that NanoIDDependency builds upon. NanoIDGenerator is also directly
inspired by UUIDGenerator from the same library.
This library is released under the MIT license. See LICENSE for details.