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 🙏

© 2025 – Pkg Stats / Ryan Hefner

ardrive-core-js

v3.1.0

Published

ArDrive Core contains the essential back end application features to support the ArDrive CLI and Desktop apps, such as file management, Permaweb upload/download, wallet management and other common functions.

Readme

ardrive-core-js

ArDrive Core is a TypeScript library that contains the essential back end application features to support the ArDrive CLI and Desktop apps, such as file management, Permaweb upload/download, wallet management, and other common functions.

Engage with the community in Discord for more information.

Table of Contents

Installation

To add the ArDrive Core library to your project:

# Using yarn
yarn add ardrive-core-js

# Using npm
npm install ardrive-core-js

Browser Usage

For browser applications, import from the web build:

import { arDriveFactory, type ArDriveSigner } from 'ardrive-core-js/web';

See Web Build Documentation for complete browser usage guide.

Quick Start

The recommended approach for integrating with ArDrive Core is through the ArDrive class, constructed using the arDriveFactory function:

import { readJWKFile, arDriveFactory } from 'ardrive-core-js';

// Read wallet from file
const myWallet = readJWKFile('/path/to/wallet.json');

// Construct ArDrive class
const arDrive = arDriveFactory({ wallet: myWallet });

// Create a public drive and its root folder
const createDriveResult = await arDrive.createPublicDrive({
    driveName: 'My-Drive'
});

console.log('Drive ID:', createDriveResult.driveId);
console.log('Root Folder ID:', createDriveResult.rootFolderId);

Core Concepts

Entity Types

ArDrive uses a hierarchical structure:

  • Drives: Top-level containers (public or private)
  • Folders: Organize files within drives
  • Files: Individual files stored on Arweave

Each entity has a unique ID (DriveID, FolderID, FileID) and can be either public (unencrypted) or private (encrypted).

Wallet Management

import { JWKWallet } from 'ardrive-core-js';

// Create wallet from JWK
const wallet = new JWKWallet(jwkKey);

// Check wallet balance
const balance = await wallet.getBalance();

Entity IDs

Use the type-safe entity ID constructors:

import { EID, DriveID, FolderID, FileID } from 'ardrive-core-js';

// Generic entity ID
const entityId = EID('10108b54a-eb5e-4134-8ae2-a3946a428ec7');

// Specific entity IDs
const driveId = new DriveID('12345674a-eb5e-4134-8ae2-a3946a428ec7');
const folderId = new FolderID('47162534a-eb5e-4134-8ae2-a3946a428ec7');
const fileId = new FileID('98765432a-eb5e-4134-8ae2-a3946a428ec7');

API Reference

Drive Operations

Creating Drives

// Public drive
const publicDrive = await arDrive.createPublicDrive({
    driveName: 'My Public Drive'
});

// Private drive with password
const privateDrive = await arDrive.createPrivateDrive({
    driveName: 'My Private Drive',
    drivePassword: 'mySecretPassword'
});

Reading Drive Information

// Get public drive
const publicDriveInfo = await arDrive.getPublicDrive({
    driveId
});

// Get private drive (requires drive key)
const privateDriveInfo = await arDrive.getPrivateDrive({
    driveId,
    driveKey
});

// Get all drives for an address
const allDrives = await arDrive.getAllDrivesForAddress({
    address: walletAddress,
    privateKeyData: wallet.getPrivateKey()
});

Renaming Drives

// Rename public drive
await arDrive.renamePublicDrive({
    driveId,
    newName: 'Updated Drive Name'
});

// Rename private drive
await arDrive.renamePrivateDrive({
    driveId,
    driveKey,
    newName: 'Updated Private Name'
});

Folder Operations

Creating Folders

// Public folder
const publicFolder = await arDrive.createPublicFolder({
    folderName: 'Documents',
    driveId,
    parentFolderId
});

// Private folder
const privateFolder = await arDrive.createPrivateFolder({
    folderName: 'Secret Documents',
    driveId,
    driveKey,
    parentFolderId
});

Listing Folder Contents

// List public folder
const publicContents = await arDrive.listPublicFolder({
    folderId,
    maxDepth: 2, // Optional: limit recursion depth
    includeRoot: true // Optional: include root folder in results
});

// List private folder
const privateContents = await arDrive.listPrivateFolder({
    folderId,
    driveKey,
    maxDepth: 1
});

Moving and Renaming Folders

// Move folder
await arDrive.movePublicFolder({
    folderId,
    newParentFolderId
});

// Rename folder
await arDrive.renamePublicFolder({
    folderId,
    newName: 'New Folder Name'
});

File Operations

Uploading Files

import { wrapFileOrFolder } from 'ardrive-core-js';

// Wrap file for upload
const wrappedFile = wrapFileOrFolder('/path/to/file.pdf');

// Upload public file
const publicUpload = await arDrive.uploadPublicFile({
    parentFolderId,
    wrappedFile,
    conflictResolution: 'upsert' // skip, replace, upsert, or error
});

// Upload private file
const privateUpload = await arDrive.uploadPrivateFile({
    parentFolderId,
    driveKey,
    wrappedFile
});

Reading File Information

// Get public file metadata
const publicFile = await arDrive.getPublicFile({ fileId });

// Get private file metadata
const privateFile = await arDrive.getPrivateFile({
    fileId,
    driveKey
});

Moving and Renaming Files

// Move file
await arDrive.movePublicFile({
    fileId,
    newParentFolderId
});

// Rename file
await arDrive.renamePublicFile({
    fileId,
    newName: 'renamed-file.pdf'
});

Bulk Operations

Upload Multiple Files and Folders

import { wrapFileOrFolder, EntityKey } from 'ardrive-core-js';

// Prepare entities for upload
const folder1 = wrapFileOrFolder('/path/to/folder1');
const folder2 = wrapFileOrFolder('/path/to/folder2');
const file1 = wrapFileOrFolder('/path/to/file1.txt');

// Upload everything in one operation
const bulkUpload = await arDrive.uploadAllEntities({
    entitiesToUpload: [
        // Public folder
        {
            wrappedEntity: folder1,
            destFolderId: rootFolderId
        },
        // Private folder
        {
            wrappedEntity: folder2,
            destFolderId: rootFolderId,
            driveKey: privateDriveKey
        },
        // Public file
        {
            wrappedEntity: file1,
            destFolderId: someFolderId
        }
    ],
    conflictResolution: 'upsert'
});

// Results include all created entities
console.log('Created folders:', bulkUpload.created.length);
console.log('Total cost:', bulkUpload.totalCost.toString());

Create Folder and Upload Contents

// Create folder and upload all children
const folderWithContents = await arDrive.createPublicFolderAndUploadChildren({
    parentFolderId,
    wrappedFolder: wrapFileOrFolder('/path/to/folder'),
    conflictResolution: 'skip'
});

Download Operations

Download Files

// Download public file
const publicData = await arDrive.downloadPublicFile({
    fileId
});
// publicData is a Buffer/Uint8Array

// Download private file (automatically decrypted)
const privateData = await arDrive.downloadPrivateFile({
    fileId,
    driveKey
});

Download Folders

// Download entire folder
const folderData = await arDrive.downloadPublicFolder({
    folderId,
    destFolderPath: '/local/download/path'
});

// Download private folder
const privateFolderData = await arDrive.downloadPrivateFolder({
    folderId,
    driveKey,
    destFolderPath: '/local/download/path'
});

Encryption & Security

Key Derivation

import { deriveDriveKey, deriveFileKey } from 'ardrive-core-js';

// Derive drive key from password
const driveKey = await deriveDriveKey('myPassword', driveId.toString(), JSON.stringify(wallet.getPrivateKey()));

// File keys are automatically derived from drive keys
const fileKey = await deriveFileKey(driveKey, fileId);

Manual Encryption/Decryption

import { driveEncrypt, driveDecrypt } from 'ardrive-core-js';

// Encrypt data
const { cipher, cipherIV } = await driveEncrypt(driveKey, data);

// Decrypt data
const decrypted = await driveDecrypt(cipherIV, driveKey, cipher);

Pricing & Cost Estimation

// Get price estimator
const priceEstimator = arDrive.getArDataPriceEstimator();

// Estimate cost for data size
const cost = await priceEstimator.getARPriceForByteCount(
    new ByteCount(1024 * 1024) // 1MB
);

// Get base Winston price (without tips)
const basePrice = await priceEstimator.getBaseWinstonPriceForByteCount(
    new ByteCount(5 * 1024 * 1024) // 5MB
);

Custom Metadata

Attach custom metadata to files:

const fileWithMetadata = wrapFileOrFolder('/path/to/file.txt', 'text/plain', {
    metaDataJson: {
        'Custom-Field': 'Custom Value',
        Version: '1.0'
    },
    metaDataGqlTags: {
        'App-Name': ['MyApp'],
        'App-Version': ['1.0.0']
    },
    dataGqlTags: {
        'Content-Type': ['text/plain']
    }
});

// Upload with custom metadata
await arDrive.uploadPublicFile({
    parentFolderId,
    wrappedFile: fileWithMetadata
});

Conflict Resolution

Available strategies when uploading files/folders that already exist:

// Skip existing files
await arDrive.uploadAllEntities({
  entitiesToUpload: [...],
  conflictResolution: 'skip'
});

// Replace all existing files
await arDrive.uploadAllEntities({
  entitiesToUpload: [...],
  conflictResolution: 'replace'
});

// Update only if content differs (default)
await arDrive.uploadAllEntities({
  entitiesToUpload: [...],
  conflictResolution: 'upsert'
});

// Rename conflicting files
await arDrive.uploadAllEntities({
  entitiesToUpload: [...],
  conflictResolution: 'rename'
});

// Throw error on conflicts
await arDrive.uploadAllEntities({
  entitiesToUpload: [...],
  conflictResolution: 'error'
});

// Interactive prompt (CLI only)
await arDrive.uploadAllEntities({
  entitiesToUpload: [...],
  conflictResolution: 'ask'
});

Advanced Features

Turbo Integration

Enable Turbo for optimized uploads:

// Node.js
const arDriveWithTurbo = arDriveFactory({
    wallet: myWallet,
    turboSettings: {
        turboUploadUrl: new URL('https://upload.ardrive.io')
    }
});

// Browser
import { arDriveFactory } from 'ardrive-core-js/web';

const arDrive = arDriveFactory({
    signer: myBrowserSigner,
    turboSettings: {
        turboUploadUrl: new URL('https://upload.ardrive.io')
    }
});

// Uploads will automatically use Turbo
const result = await arDriveWithTurbo.uploadAllEntities({
    entitiesToUpload: [{ wrappedEntity, destFolderId }]
});

Bundle Support

Large uploads are automatically bundled for efficiency:

// Bundling happens automatically for multiple files
const bulkResult = await arDrive.uploadAllEntities({
    entitiesToUpload: manyFiles
    // Bundling is handled internally
});

Manifest Creation

Create Arweave manifests for web hosting:

// Create a manifest for a folder
const manifest = await arDrive.uploadPublicManifest({
    folderId,
    destManifestName: 'index.html',
    conflictResolution: 'upsert'
});

// Access: https://arweave.net/{manifestId}

Progress Tracking

Enable upload progress logging:

# Set environment variable
export ARDRIVE_PROGRESS_LOG=1

Progress will be logged to stderr:

Uploading file transaction 1 of total 2 transactions...
Transaction _GKQasQX194a364Hph8Oe-oku1AdfHwxWOw9_JC1yjc Upload Progress: 0%
Transaction _GKQasQX194a364Hph8Oe-oku1AdfHwxWOw9_JC1yjc Upload Progress: 35%
Transaction _GKQasQX194a364Hph8Oe-oku1AdfHwxWOw9_JC1yjc Upload Progress: 66%
Transaction _GKQasQX194a364Hph8Oe-oku1AdfHwxWOw9_JC1yjc Upload Progress: 100%

Caching

ArDrive Core maintains a metadata cache for improved performance:

# Cache locations
Windows: <os.homedir()>/ardrive-caches/metadata
Non-Windows: <os.homedir()>/.ardrive/caches/metadata

Enable cache logging:

export ARDRIVE_CACHE_LOG=1

Anonymous Operations

Use ArDrive without a wallet for read-only operations:

import { arDriveAnonymousFactory } from 'ardrive-core-js';

const anonymousArDrive = arDriveAnonymousFactory({});

// Read public data
const publicFile = await anonymousArDrive.getPublicFile({ fileId });
const folderContents = await anonymousArDrive.listPublicFolder({ folderId });

Community Features

Send tips to the ArDrive community:

// Send community tip
await arDrive.sendCommunityTip({
    tokenAmount: new Winston(1000000000000), // 1 AR
    walletAddress,
    communityWalletAddress
});

Development

Environment Setup

We use nvm and Yarn for development:

  1. Install nvm using their instructions
  2. Install correct Node version: nvm install && nvm use
  3. Install Yarn 3.x: Follow Yarn installation
  4. Enable git hooks: yarn husky install
  5. Install dependencies: yarn install --check-cache

Recommended VS Code Extensions

Building

# Build Node.js library
yarn build

# Build web bundle
yarn build:web

# Build both
yarn build:all

# Development mode with watch
yarn dev

Linting and Formatting

# Run linter
yarn lint

# Fix linting issues
yarn lintfix

# Format code
yarn format

# Type checking
yarn typecheck

Testing

This library uses Mocha with Chai and Sinon for testing.

Running Tests

# Run all tests
yarn test

# Run specific tests
yarn test -g 'My specific test'

# Run with coverage
yarn coverage

# Run browser tests (Playwright)
yarn test:playwright

# Power assert for debugging
yarn power-assert -g 'My test case'

Test Organization

  • Unit tests: Located next to source files (*.test.ts)
  • Integration tests: Located in /tests directory

ArLocal Testing

For integration testing with a local Arweave instance:

yarn arlocal-docker-test

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

AGPL-3.0-or-later

Support