Simple and unopinionated ACME client
Clone or download
Latest commit 5909b38 Nov 7, 2018

acme-client Build Status

A simple and unopinionated ACME client.

This module is written to handle communication with a Boulder/Let's Encrypt-style ACME API.

ACME specification:

Information on how the Boulder/Let's Encrypt API diverges from the ACME spec:

ACME compatibility

acme-client API Style
v2.x ACMEv2 Promise
v1.x ACMEv1 callback


$ npm install acme-client


const acme = require('acme-client');

const accountPrivateKey = '<PEM encoded private key>';

const client = new acme.Client({
    accountKey: accountPrivateKey

Directory URLs;;


For key pair generation and Certificate Signing Requests, acme-client supports multiple interchangeable cryptographic engines.

acme.forge -- docs/

Recommended when node >= v10.12.0 or OpenSSL CLI dependency can not be met.

Uses node-forge, a pure JavaScript implementation of the TLS protocol.

This engine has no external dependencies since it is completely implemented in JavaScript, however CPU-intensive tasks (like generating a large size key pair) has a performance penalty and will be slower than doing it natively.

This caveat is removed in Node v10.12.0 with the introduction of crypto.generateKeyPair(), a native Node API for key pair generation. The forge engine will automatically use this API when available.


const privateKey = await acme.forge.createPrivateKey();

const [certificateKey, certificateCsr] = await acme.forge.createCsr({
    commonName: '*',
    altNames: ['']

acme.openssl -- docs/

Recommended when node < v10.12.0 and OpenSSL CLI dependency can be met.

Uses openssl-wrapper to execute commands using the OpenSSL CLI.

This backend requires OpenSSL to be installed and available in $PATH.


const privateKey = await acme.openssl.createPrivateKey();

const [certificateKey, certificateCsr] = await acme.openssl.createCsr({
    commonName: '*',
    altNames: ['']

Auto mode

For convenience an auto() method is included in the client that takes a single config object. This method will handle the entire process of getting a certificate for one or multiple domains.

A full example can be found at examples/auto.js.

Documentation: docs/


const autoOpts = {
    csr: '<PEM encoded CSR>',
    email: '',
    termsOfServiceAgreed: true,
    challengeCreateFn: async (authz, challenge, keyAuthorization) => {},
    challengeRemoveFn: async (authz, challenge, keyAuthorization) => {}

const certificate = await;


For more fine-grained control you can interact with the ACME API using the methods documented below.

A full example can be found at examples/api.js.

Documentation: docs/


const account = await client.createAccount({
    termsOfServiceAgreed: true,
    contact: ['']

const order = await client.createOrder({
    identifiers: [
        { type: 'dns', value: '' },
        { type: 'dns', value: '*' }


acme-client uses debug for debugging which can be enabled by running

DEBUG=acme-client node index.js