Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/bluesky-social/atproto/llms.txt

Use this file to discover all available pages before exploring further.

Overview

@atproto/common provides shared utilities and helpers for building AT Protocol servers and Node.js applications. This package is specifically designed for server-side usage and is not browser-compatible. For browser-compatible utilities, use @atproto/common-web.
This package re-exports all utilities from @atproto/common-web and adds Node.js-specific functionality.

Installation

npm install @atproto/common

Main Exports

Logger Utilities

Structured logging utilities built on Pino.
import { subsystemLogger } from '@atproto/common'

// Create a subsystem logger
const log = subsystemLogger('my-service')

log.info({ msg: 'Service started', port: 3000 })
log.error({ err, msg: 'Request failed' })
log.debug({ user: 'alice.bsky.social', msg: 'Processing request' })

Environment Variables

Control logging behavior with these environment variables:
  • LOG_ENABLED - Enable/disable logging (true, t, 1 to enable)
  • LOG_LEVEL - Set log level (debug, info, warn, error, fatal)
  • LOG_SYSTEMS - Space or comma-separated list of subsystems to enable
  • LOG_DESTINATION - Path to log file (defaults to stdout)

API

subsystemLogger
(name: string) => pino.Logger
Create a logger for a specific subsystem. Subsystems can be individually enabled via LOG_SYSTEMS.
const dbLogger = subsystemLogger('database')
const apiLogger = subsystemLogger('api')

Environment Variable Helpers

Utilities for reading and parsing environment variables.
import { envInt, envStr, envBool, envList } from '@atproto/common'

// Parse integer with fallback
const port = envInt('PORT') ?? 3000

// Get string value
const hostname = envStr('HOSTNAME')

// Parse boolean
const enableCache = envBool('ENABLE_CACHE') ?? false

// Parse comma-separated list
const allowedOrigins = envList('ALLOWED_ORIGINS')

API

envInt
(name: string) => number | undefined
Parse environment variable as integer. Returns undefined if not set or invalid.
envStr
(name: string) => string | undefined
Get environment variable as string. Returns undefined if not set or empty.
envBool
(name: string) => boolean | undefined
Parse environment variable as boolean. Accepts 'true', '1', 'false', '0'. Returns undefined for other values.
envList
(name: string) => string[]
Parse comma-separated environment variable into array. Returns empty array if not set.

Buffer Utilities

Utilities for working with binary data and buffers.
import { 
  bufferToStream,
  streamToBuffer,
  streamToNodeBuffer,
  readStreamAsBuffer
} from '@atproto/common'

// Convert buffer to stream
const stream = bufferToStream(Buffer.from('hello'))

// Convert stream to buffer
const buf = await streamToBuffer(stream)

// Convert web ReadableStream to Node Buffer
const nodeBuf = await streamToNodeBuffer(webStream)

Stream Utilities

Utilities for working with Node.js streams.
import { 
  cloneStream,
  streamSize,
  MaxSizeChecker
} from '@atproto/common'

// Clone a stream for multiple consumers
const [stream1, stream2] = cloneStream(originalStream)

// Check stream size
const size = await streamSize(stream)

// Create a size-checking transform stream
const checker = new MaxSizeChecker(1024 * 1024) // 1MB max
inputStream.pipe(checker).pipe(outputStream)

File System Utilities

Utilities for file system operations.
import { 
  ensureDir,
  fileExists,
  readFile,
  writeFile,
  deleteFile
} from '@atproto/common'

// Ensure directory exists
await ensureDir('/path/to/dir')

// Check if file exists
const exists = await fileExists('/path/to/file')

// Read file as buffer
const data = await readFile('/path/to/file')

// Write buffer to file
await writeFile('/path/to/file', data)

// Delete file
await deleteFile('/path/to/file')

IPLD Utilities

Utilities for working with IPLD (InterPlanetary Linked Data).
import { 
  verifyBlocks,
  readFromBlockstore,
  writeToBlockstore
} from '@atproto/common'

import { BlockMap } from '@atproto/repo'

// Verify block integrity
await verifyBlocks(cid, blockMap)

// Read IPLD data from blockstore
const data = await readFromBlockstore(cid, blockstore)

// Write IPLD data to blockstore
await writeToBlockstore(obj, blockstore)

Date Utilities

Date parsing and validation utilities.
import { parseDate, isValidDate } from '@atproto/common'

// Parse ISO 8601 date string
const date = parseDate('2024-03-04T12:00:00Z')

// Validate date string
if (isValidDate('2024-03-04T12:00:00Z')) {
  // Valid ISO 8601 date
}

Obfuscation Utilities

Utilities for obfuscating sensitive data in logs.
import { obfuscateString } from '@atproto/common'

// Obfuscate sensitive string (shows first/last chars)
const obfuscated = obfuscateString('my-secret-token-12345')
// Returns: 'my...45'

// Useful for logging
log.info({ 
  token: obfuscateString(apiToken), 
  msg: 'API request' 
})

Re-exported from @atproto/common-web

All utilities from @atproto/common-web are also available:
  • TID (Timestamp Identifier) generation
  • Async utilities (retry, wait, bailableWait)
  • Array utilities (chunkArray, dedupeStrs, asyncFilter)
  • Object utilities (omit, noUndefinedVals)
  • DID document utilities
  • String and binary conversion utilities
import { TID, retry, chunkArray } from '@atproto/common'

// All common-web utilities work the same way
const tid = TID.nextStr()
const chunks = chunkArray([1, 2, 3, 4, 5], 2)

Usage Example

Complete example of a simple AT Protocol server using common utilities:
import express from 'express'
import { 
  subsystemLogger, 
  envInt, 
  envStr, 
  envBool 
} from '@atproto/common'

// Create logger
const log = subsystemLogger('server')

// Load configuration
const config = {
  port: envInt('PORT') ?? 3000,
  hostname: envStr('HOSTNAME') ?? 'localhost',
  debug: envBool('DEBUG') ?? false
}

// Create server
const app = express()

app.get('/health', (req, res) => {
  log.debug({ msg: 'Health check' })
  res.json({ status: 'ok' })
})

app.listen(config.port, () => {
  log.info({ 
    port: config.port, 
    hostname: config.hostname,
    msg: 'Server started' 
  })
})

TypeScript Types

The package is written in TypeScript and includes complete type definitions. All utilities are fully typed.
import type { Logger } from 'pino'
import { subsystemLogger } from '@atproto/common'

// Logger type is exported from pino
const log: Logger = subsystemLogger('my-service')

@atproto/common-web

Browser-compatible shared utilities

@atproto/xrpc-server

Server-side XRPC implementation

@atproto/pds

Personal Data Server implementation

@atproto/bsky

Bluesky AppView implementation

License

This project is dual-licensed under MIT and Apache 2.0 terms.

Build docs developers (and LLMs) love