npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

intuned

v0.0.1

Published

Build and query an LMDB representation of iOS Messages backups.

Readme

intuned

intuned builds a query-friendly LMDB representation of an iOS Messages backup and exposes a small, hierarchical API that mirrors how people think about conversations: backup → chats → messages → attachments / reactions / participants.

Install

npm install intuned lmdb

Quick Start

import { intuned } from "intuned"

const backupId = process.env.ITUNED_BACKUP_ID
if (!backupId) throw new Error("Set ITUNED_BACKUP_ID first")

// Build once
await intuned.backups.build(backupId)

// Load and query
const backup = intuned.backups.load(backupId)

const chat = backup.chats.get(1)
if (!chat) throw new Error("Chat not found")

const messages = chat.messages.latest(30)
for (const message of messages) {
  console.log(message.text)
}

await backup.close()

API

Entry Point

import { intuned } from "intuned"

// Build an LMDB dataset from an iOS backup
await intuned.backups.build(backupId)

// Load a previously built backup
const backup = intuned.backups.load(backupId)

// List all built backup IDs in the current directory
const ids = intuned.backups.list()

Build Progress

await intuned.backups.build(backupId, {
  onProgress(event) {
    console.log(event.stage, event.processed, event.total)
  }
})

Event shape:

{
  stage: "messages" | "attachments" | "participants" | "chats" | "reactions"
  processed: number
  total: number
}

Backup

Every property on a backup is a collection.

backup.id           // string
backup.chats        // GlobalChatCollection
backup.messages     // GlobalMessageCollection
backup.attachments  // GlobalAttachmentCollection
backup.participants // GlobalParticipantCollection
backup.reactions    // GlobalReactionCollection
backup.close()      // Promise<void>

A collection always exposes list(), get(id), and count().

Chat

const chats = backup.chats.list()
const chat = backup.chats.get(chatId)

chat.id
chat.displayName
chat.participantIds

chat.messages     // MessageCollection (scoped to this chat)
chat.attachments  // ChatAttachmentCollection
chat.participants // ChatParticipantCollection

Message Querying

Message querying is concentrated in chat.messages:

chat.messages.list()
chat.messages.get(messageId)
chat.messages.count()
chat.messages.latest(limit)
chat.messages.before(timestamp, limit)
chat.messages.after(timestamp, limit)
chat.messages.day("2024-03-09")
chat.messages.range(startTimestamp, endTimestamp)

Scroll implementation example:

const page1 = chat.messages.latest(50)
const page2 = chat.messages.before(page1[0].timestamp, 50)

Message

message.id
message.chatId
message.participantId
message.text
message.timestamp
message.isFromMe

message.chat()        // Chat | undefined
message.participant() // Participant | undefined
message.attachments() // Array<Attachment>
message.reactions()   // Array<Reaction>

Attachment

backup.attachments.list()
backup.attachments.get(attachmentId)
backup.attachments.count()
backup.attachments.range(offset, limit)

chat.attachments.list()
chat.attachments.get(attachmentId)
chat.attachments.count()

attachment.id
attachment.messageId
attachment.chatId
attachment.path
attachment.mimeType
attachment.message()  // Message | undefined
attachment.chat()     // Chat | undefined

Participant

backup.participants.list()
backup.participants.get(participantId)
backup.participants.count()

participant.id
participant.handle
participant.service
participant.messages() // Array<Message>

Reaction

backup.reactions.list()
backup.reactions.get(reactionId)
backup.reactions.count()

reaction.id
reaction.targetMessageGuid
reaction.participantId
reaction.reactionType
reaction.timestamp
reaction.messageId
reaction.message()     // Message | undefined
reaction.participant() // Participant | undefined

Runtime Model

intuned
  backups
    build()
    load()
    list()

Backup
  chats
  messages
  attachments
  participants
  reactions

Chat
  messages
  attachments
  participants

Message
  chat()
  participant()
  attachments()
  reactions()

Attachment
  message()
  chat()

Participant
  messages()

Reaction
  message()
  participant()

Error Behavior

  • Build functions throw when required backup files are missing.
  • get() methods return undefined when an entity is not found.

Platform Notes

  • On Windows, backup discovery uses %APPDATA%/Apple Computer/MobileSync/Backup/<backupId>.
  • On macOS, backup discovery falls back to ~/Library/Application Support/MobileSync/Backup/<backupId>.