fargone / docs / lib

Node.js library

fargone-cli ships a typed client you can import in your own code — the same API the CLI uses, with no CLI side effects. Deploy apps, manage env vars, provision databases, upload CDN files, all from scripts, serverless functions, or CI.

npm install fargone-cli

Quick start

import { FargoneClient } from "fargone-cli";

const client = new FargoneClient({
  host: "https://fargone.sh",
  token: process.env.FARGONE_TOKEN,
});

const me = await client.me();
console.log(me.user.handle, me.quota.maxApps);

Authentication

With a token

Pass an OAuth access token directly (from the device flow or any OAuth grant):

const client = new FargoneClient({
  host: "https://fargone.sh",
  token: "oat_…",
});

Reusing the CLI session

FargoneClient.forHost() reads the credentials stored by fargone login and auto-refreshes expired tokens:

const client = FargoneClient.forHost("https://fargone.sh");
// token is loaded from ~/.config/fargone/config.json

Apps

// list
const apps = await client.listApps();

// create
const app = await client.createApp({
  name: "my-app",
  source: "github",
  repoUrl: "https://github.com/you/repo",
  repoBranch: "main",
});

// detail (env, resources, deployments)
const detail = await client.getApp("my-app");

// update
await client.updateApp("my-app", { autoDeploy: true });

// delete
await client.deleteApp("my-app");

// stop / restart
await client.stopApp("my-app");
await client.restartApp("my-app");

Deploys

// deploy from a connected GitHub repo
const dep = await client.deploy("my-app");

// deploy a zip (Uint8Array)
const zip = new TextEncoder().encode(fs.readFileSync("app.zip"));
const dep2 = await client.deployZip("my-app", zip, "v2.zip");

// wait for it to finish
const result = await client.waitForDeployment("my-app", dep2.id, {
  timeoutMs: 10 * 60 * 1000,
});
console.log(result.deployment.status); // "SUCCEEDED"

Environment variables

// list
const env = await client.listEnv("my-app");

// set
await client.setEnv("my-app", "NODE_ENV", "production");

// unset
await client.unsetEnv("my-app", "DEBUG");

Databases

// add
const db = await client.addDb("my-app", "POSTGRES");
console.log(db.connectionUrl);

// list (on the app detail)
const detail = await client.getApp("my-app");
console.log(detail.resources);

// delete
await client.deleteDb(db.id);

CDN

// list my files
const info = await client.listCdn();
console.log(info.used, info.limit);

// upload a file
const fileBytes = new TextEncoder().encode("hello world");
const file = await client.uploadCdn(fileBytes, "greeting.txt", "text/plain");
console.log(file.url);

// get managed CDN env vars for an app
const cdnEnv = await client.cdnEnv("my-app");
// cdnEnv.FARGONE_CDN_URL, cdnEnv.FARGONE_CDN_TOKEN, etc.

// rotate the app's CDN token
const newEnv = await client.rotateCdn("my-app");

// delete a file
await client.deleteCdn(file.id);

Logs

const lines = await client.getLogs("my-app", { kind: "runtime" });
lines.forEach((l) => console.log(l.ts, l.line));

// build logs
const buildLines = await client.getLogs("my-app", { kind: "build" });

Quota

await client.requestQuota("CDN_STORAGE", "500", "need more for media uploads");

Error handling

import { FargoneClient, ApiError } from "fargone-cli";

try {
  await client.getApp("nope");
} catch (e) {
  if (e instanceof ApiError) {
    console.log(e.status); // 404
    console.log(e.message); // "app not found"
  }
}

Types

All domain types are exported from fargone-cli:

import type {
  Me,
  App,
  AppDetail,
  Deployment,
  EnvVar,
  DbResource,
  CdnFile,
  CdnInfo,
  CdnEnvVars,
  QuotaRequest,
  // …and more
} from "fargone-cli";

Further reading

  • CLI — the terminal interface over the same API
  • REST API — raw HTTP reference
  • OAuth provider — how tokens work under the hood