Skip to main content
The TypeScript SDK is currently in preview and the API is subject to change.
The TypeScript SDK is intended for environments where FUSE mounting is not available — such as serverless functions, containers without CAP_SYS_ADMIN, browser-adjacent runtimes, or CI/CD pipelines. If you can mount via FUSE using the Archil CLI, prefer that approach: it provides full POSIX compatibility, works with any language or tool, and benefits from the client’s local caching layer.
The Archil TypeScript SDK provides two packages:
PackageDescription
@archildata/clientCore client with native (NAPI) bindings to the Archil protocol. Provides low-level inode operations and a control plane API.
@archildata/just-bashHigher-level filesystem adapter built on @archildata/client. Provides path-based operations (readFile, writeFile, mkdir, etc.) and an interactive shell.
Most applications should use both packages together: @archildata/client to establish the connection and @archildata/just-bash for filesystem operations.

Platform support

The native module ships pre-built binaries for:
  • Linux x64 (glibc)
  • Linux ARM64 (glibc)
  • macOS ARM64 (Apple Silicon)
Node.js 18 or later is required.

Installation

npm install @archildata/client @archildata/just-bash

Connecting to a disk

IAM authentication (AWS)

When running on an EC2 instance or any environment with AWS credentials available, the client authenticates automatically using IAM:
import { ArchilClient } from "@archildata/client";

const client = await ArchilClient.connect({
  region: "aws-us-east-1",
  diskName: "myorg/mydisk",
});

Token authentication

Outside of AWS, or when using explicit credentials, pass an auth token:
const client = await ArchilClient.connect({
  region: "aws-us-east-1",
  diskName: "myorg/mydisk",
  authToken: process.env.ARCHIL_TOKEN,
});
Store tokens in environment variables rather than hardcoding them. The SDK checks ARCHIL_TOKEN automatically if no authToken is provided.

Connection options

interface SimpleConnectionConfig {
  region: string;       // e.g., "aws-us-east-1", "gcp-us-central1"
  diskName: string;     // "org/disk-name" or disk ID "dsk-xxx"
  authToken?: string;   // Explicit token (defaults to IAM)
  stsRegion?: string;   // Override STS region for IAM auth
  logLevel?: string;    // "trace" | "debug" | "info" | "warn" | "error"
}

Environment variables

The SDK reads these environment variables as fallbacks:
VariableDescription
ARCHIL_TOKENAuthentication token
ARCHIL_REGIONRegion identifier
ARCHIL_DISKDisk name
ARCHIL_LOG_LEVELLog level
ARCHIL_API_KEYAPI key for control plane operations

Filesystem operations

Create an ArchilFs instance to work with paths instead of raw inode IDs:
import { ArchilClient } from "@archildata/client";
import { ArchilFs } from "@archildata/just-bash";

const client = await ArchilClient.connect({
  region: "aws-us-east-1",
  diskName: "myorg/mydisk",
});

const fs = await ArchilFs.create(client);

Reading files and directories

// Read a file as a UTF-8 string
const content = await fs.readFile("/config.json");

// Read a file as a buffer
const buffer = await fs.readFileBuffer("/image.png");

// List a directory
const names = await fs.readdir("/data");

// List with file types
const entries = await fs.readdirWithFileTypes("/data");
for (const entry of entries) {
  console.log(`${entry.name} (file=${entry.isFile}, dir=${entry.isDirectory})`);
}

// Get file metadata
const info = await fs.stat("/data/report.csv");
console.log(`size=${info.size}, modified=${info.mtime}`);

// Check if a path exists
if (await fs.exists("/data/report.csv")) {
  // ...
}

Writing files and directories

Write operations require a delegation on the target. The high-level writeFile and mkdir methods handle delegation management automatically when possible.
// Write a file (atomic: writes to a temp file, then renames)
await fs.writeFile("/output/result.json", JSON.stringify(data));

// Append to a file
await fs.appendFile("/logs/app.log", `${new Date().toISOString()} event\n`);

// Create a directory
await fs.mkdir("/output/reports");

// Create nested directories
await fs.mkdir("/output/reports/2026/q1", { recursive: true });

// Copy a file
await fs.cp("/data/source.txt", "/data/copy.txt");

// Copy a directory tree
await fs.cp("/data/input", "/data/backup", { recursive: true });

// Move / rename
await fs.mv("/data/old-name.txt", "/data/new-name.txt");

// Create a symlink
await fs.symlink("/data/latest", "/data/reports/2026");

// Delete a file
await fs.rm("/data/temp.txt");

// Delete a directory tree
await fs.rm("/data/old-output", { recursive: true });

Permissions and timestamps

// Change permissions
await fs.chmod("/script.sh", 0o755);

// Update access and modification times
await fs.utimes("/data/file.txt", new Date(), new Date());

Subdirectory scoping

You can scope an ArchilFs instance to a subdirectory, making it the root of all path operations. See Subdirectory Mounts for details.
const fs = await ArchilFs.create(client, {
  subdirectory: "/data/project",
});

// "/" now refers to /data/project on the disk
const files = await fs.readdir("/");

Delegation management

When multiple clients access the same disk, you must manage delegations to coordinate write access. The low-level client exposes delegation operations directly:
// Acquire exclusive write access to a file or directory
await client.checkout(inodeId);

// Force-revoke another client's delegation
await client.checkout(inodeId, { force: true });

// Release write access
await client.checkin(inodeId);

// Release all delegations
const count = await client.checkinAll();

// List current delegations
const delegations = client.listDelegations();
for (const d of delegations) {
  console.log(`inode ${d.inodeId}: ${d.state}`);
}
Using force: true on checkout will immediately revoke another client’s delegation. Any unflushed writes from that client will be lost.

Low-level inode operations

For advanced use cases, ArchilClient provides direct inode-level operations:
const user = { uid: 1000, gid: 1000 };

// Look up a child by name
const entry = await client.lookupInode(parentInodeId, "file.txt", { user });
if (entry) {
  console.log(`inode=${entry.inodeId}, size=${entry.attributes.size}`);
}

// Get attributes
const attrs = await client.getAttributes(inodeId, { user });

// Create a file
const result = await client.create(parentInodeId, "new.txt", {
  inodeType: "File",
  uid: 1000,
  gid: 1000,
  mode: 0o644,
}, { user });

// Write data at an offset (requires checkout first)
await client.checkout(result.inodeId);
await client.writeData(result.inodeId, 0, Buffer.from("hello"));
await client.checkin(result.inodeId);

// Read data at an offset
const buf = await client.readInode(inodeId, 0, 1024, { user });

// Paginated directory listing
const handle = await client.openDirectory(dirInodeId, { user });
let cursor;
do {
  const page = await client.readDirectory(dirInodeId, handle, 1000, cursor, { user });
  for (const entry of page.entries) {
    console.log(entry.name);
  }
  cursor = page.nextCursor;
} while (cursor);
await client.closeDirectory(dirInodeId, handle);

Control plane API

The Archil class provides access to the control plane for managing disks and tokens programmatically:
import { Archil } from "@archildata/client/api";

const archil = new Archil({
  apiKey: process.env.ARCHIL_API_KEY,
  region: "aws-us-east-1",
});

// List disks
const disks = await archil.disks.list();

// Create a disk
const disk = await archil.disks.create({
  name: "my-disk",
  mounts: [{
    type: "s3",
    bucketName: "my-bucket",
    accessKeyId: "xxx",
    secretAccessKey: "xxx",
  }],
});

// Manage tokens
const token = await archil.tokens.create({ name: "ci-token" });
const tokens = await archil.tokens.list();
await archil.tokens.delete(token.id);
The control plane API is also available as a REST API for non-TypeScript environments.

Interactive shell

The @archildata/just-bash package includes an interactive shell for exploring and modifying disks from the terminal:
# Connect to a disk
npx @archildata/just-bash aws-us-east-1 myorg/mydisk

# With explicit token
ARCHIL_TOKEN=xxx npx @archildata/just-bash aws-us-east-1 myorg/mydisk

# Quick start with an S3 bucket
npx @archildata/just-bash s3://my-bucket --api-key adt_xxx

# Mount a subdirectory
npx @archildata/just-bash aws-us-east-1 myorg/mydisk:/data
The shell supports standard commands (ls, cat, cp, mv, rm, mkdir) plus Archil-specific commands for delegation management:
archil checkout /path      # Acquire write delegation
archil checkin /path       # Release write delegation
archil list-delegations    # Show held delegations

Closing the connection

Always close the client when finished to flush pending writes and release delegations:
await client.close();
close() syncs all outstanding writes to the server and releases all held delegations before disconnecting.