ACME Client for Node.js
raw JSON →acme-client is a simple and unopinionated Node.js library designed to interact with ACME (Automatic Certificate Management Environment) APIs, such as those provided by Let's Encrypt, Buypass, Google, and ZeroSSL. It adheres to RFC 8555 for ACME protocol communication. The current stable version is 5.4.0, requiring Node.js >= 16.0.0. The library primarily focuses on certificate management tasks, including account registration, order processing, and challenge fulfillment, supporting both RSA and ECDSA keys through native Node.js cryptography. It differentiates itself by being unopinionated and providing direct control over the ACME workflow, rather than an 'auto-mode' by default (though auto mode is available), and ships with TypeScript types for improved developer experience. While major versions have specific Node.js requirements, the project appears to release updates as needed, rather than on a fixed cadence.
Common errors
error ERR_OSSL_EVP_UNSUPPORTED: Unsupported cipher algorithm ↓
acme-client v5+). If generating keys, use modern algorithms (e.g., RSA 2048-bit or ECDSA P-256) and standard encodings (PKCS8 for private keys, SPKI for public keys). error Error: Invalid response from ACME server (status: 400, type: urn:ietf:params:acme:error:malformed) ↓
acme.setLogger) to see the full request and response for more details. error Error: Account terms of service must be agreed ↓
client.createAccount(), ensure you set termsOfServiceAgreed: true. You should only do this after your application (or end-user) has reviewed and accepted the current terms of service. Warnings
breaking Version 5.x of `acme-client` requires Node.js version 16 or newer. Older Node.js versions (v10, v8, v4) are compatible with earlier major versions (v4.x, v3.x, v2.x/v1.x respectively). ↓
breaking Older versions of `acme-client` (pre-v5) might have different API signatures or return types. Always consult the upgrade guide or changelog when moving between major versions. ↓
gotcha When using external account binding (EAB), ensure that the `kid` and `hmacKey` are correctly provided in the client constructor. Incorrect EAB credentials will lead to account creation or update failures. ↓
gotcha It's critical to store ACME account private keys securely and persist them across application restarts. Losing the account key means losing control over certificates associated with that account. ↓
Install
npm install acme-client yarn add acme-client pnpm add acme-client Imports
- Client wrong
const Client = require('acme-client').Client;correctimport { Client } from 'acme-client'; - directory wrong
import directory from 'acme-client/directory';correctimport { directory } from 'acme-client'; - AcmeClient
import type { Client as AcmeClient } from 'acme-client';
Quickstart
import { Client, directory } from 'acme-client';
import { createPrivateKey } from 'crypto';
async function runAcmeClient() {
// In a real application, load this from a secure source or generate it once
const accountPrivateKey = createPrivateKey({
type: 'rsa',
modulusLength: 2048,
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem'
}
}).export({ type: 'pkcs8', format: 'pem' }).toString();
console.log('Using account private key (truncated):', accountPrivateKey.substring(0, 50) + '...');
const client = new Client({
directoryUrl: directory.letsencrypt.staging,
accountKey: accountPrivateKey,
});
console.log('ACME client initialized with Let\'s Encrypt staging directory.');
// Example: Register a new ACME account or get existing one
const account = await client.createAccount({
termsOfServiceAgreed: true,
contact: ['mailto:test@example.com'],
});
console.log('ACME account registered/fetched:', account);
const accountUrl = client.getAccountUrl();
console.log('Account URL:', accountUrl);
// In a real scenario, you'd now proceed to create an order, generate a CSR, and fulfill challenges.
// This quickstart only covers client initialization and account registration.
}
runAcmeClient().catch(console.error);