An UNOFFICIAL TypeScript-based, promise-driven Node.js library for interacting with the CapRover API.
This library is a port of the excellent Python library caprover-api by ak4zh and aims to provide similar functionality for the JavaScript ecosystem.
- Fully typed with TypeScript for a great developer experience
- Modern async/await syntax
- Manages the authentication token automatically
- Provides methods for all common CapRover operations:
- App management (list, get, create, update, delete)
- Deploying from an image, Dockerfile, or one-click app repository
- Managing custom domains and SSL certificates
- Creating and downloading server backups
- Includes a built-in retry mechanism for network-related errors
You can install the library using npm or yarn.
npm install caprover-api-jsyarn add caprover-api-jsAll methods are asynchronous and return a Promise. It is recommended to use the async/await syntax inside a try/catch block.
import { CaproverAPI } from 'caprover-api-js';OR
const { CaproverAPI } = require('caprover-api-js');Unlike the Python version, the constructor is private. You must use the static CaproverAPI.create() method to initialize the client. This method handles the asynchronous login process and returns a fully authenticated instance.
async function main() {
try {
console.log('Connecting to CapRover...');
const api = await CaproverAPI.create({
dashboardUrl: 'https://captain.your-domain.com',
password: 'your-super-secret-password',
});
console.log('Successfully connected!');
// You can now use the 'api' object to interact with CapRover
} catch (error) {
console.error('Failed to connect or execute command:', (error as Error).message);
}
}
main();Fetches all application definitions from your CapRover instance.
// (inside an async function after initialization)
const appListResponse = await api.listApps();
const apps = appListResponse.data.appDefinitions;
console.log('Available applications:');
apps.forEach(app => {
console.log(`- ${app.appName} (Instances: ${app.instanceCount})`);
});This example shows a full lifecycle: create an app, update its configuration, and deploy Nginx to it.
// (inside an async function after initialization)
const newAppName = 'my-nginx-app';
try {
console.log(`Creating new app: ${newAppName}`);
await api.createApp(newAppName, false); // hasPersistentData = false
console.log('Updating app environment variables...');
await api.updateApp(newAppName, {
envVars: [{ key: 'NGINX_VERSION', value: 'latest' }]
});
console.log(`Deploying nginx image to ${newAppName}...`);
await api.deployApp(newAppName, { imageName: 'nginx:latest' });
console.log('Deployment successful!');
} catch (error) {
console.error(`Failed to deploy ${newAppName}:`, (error as Error).message);
}You can easily deploy any app from the official one-click-apps repository.
// (inside an async function after initialization)
const appName = 'my-portainer';
try {
console.log(`Deploying Portainer from one-click repository...`);
await api.deployOneClickApp(
'portainer', // The name of the app in the repository
appName, // The name you want to give the app on your server
{} // An object for any required app variables (Portainer needs none)
);
console.log('Portainer deployed successfully!');
} catch (error) {
console.error(`Failed to deploy Portainer:`, (error as Error).message);
}This will permanently delete an application. This action is irreversible.
// (inside an async function after initialization)
const appToDelete = 'my-nginx-app';
try {
console.log(`Deleting app: ${appToDelete}`);
await api.deleteApp(appToDelete); // To also delete volumes, use: api.deleteApp(appToDelete, true)
console.log('App deleted successfully.');
} catch (error) {
console.error(`Failed to delete ${appToDelete}:`, (error as Error).message);
}This creates a full server backup and downloads it to a local file.
// (inside an async function after initialization)
try {
console.log('Starting server backup...');
// You can optionally provide a file name, e.g., api.createBackup('my-backup.tar')
const backupPath = await api.createBackup();
console.log(`Backup successfully saved to: ${backupPath}`);
} catch (error) {
console.error('Failed to create backup:', (error as Error).message);
}If you are coming from the Python version, here are the main changes to be aware of:
- Asynchronous by Default: Every API call returns a Promise. You must use
awaitto get the result. - camelCase Naming: All methods and properties use camelCase (e.g.,
listApps) instead of snake_case (e.g.,list_apps). - Static create Method: You must initialize the library with
await CaproverAPI.create()instead of calling a class constructor directly. - Error Handling: Errors are thrown via Promise rejections. Use a try/catch block to handle them.
- Response Structure: All successful API calls return a response object with the following structure:
{
status: number,
description: string,
data: { ... } // The actual payload is here
}You will typically access the result via the .data property (e.g., (await api.listApps()).data.appDefinitions).
Contributions are welcome! If you'd like to contribute, please feel free to fork the repository and submit a pull request.
To run the test suite locally:
- Clone the repository
- Install development dependencies:
npm install - Run the tests:
npm test
This project is licensed under the MIT License. See the LICENSE file for details.