Installation
@forjio/plugipay-node is a single npm package with zero runtime dependencies. This page covers installing it, which Node versions work, ESM vs. CommonJS, TypeScript setup, and what to expect from bundlers.
Install
npm install @forjio/plugipay-node
Or with your preferred package manager:
pnpm add @forjio/plugipay-node
yarn add @forjio/plugipay-node
bun add @forjio/plugipay-node
The package ships pre-built — you don't need a TypeScript or tsup toolchain to consume it.
Version requirements
| Requirement | Minimum |
|---|---|
| Node.js | >=20.0.0 |
| TypeScript (if you use it) | >=5.0 |
Node 20 is the floor because the SDK uses the global fetch, AbortController, and crypto.randomUUID() — all stable in Node 20 LTS. Older Node versions (18, 16) are not tested and not supported.
Browser usage is not supported. The SDK imports from node:crypto and is designed to hold a long-lived secret — both of which are wrong for a browser context. If you need to call Plugipay from a browser, build a thin server-side proxy in Node and have the browser call that proxy.
ESM vs CommonJS
The package ships both flavors:
| Entry | File | Used when |
|---|---|---|
import |
dist/index.js |
Your project is ESM ("type": "module") or uses import syntax. |
require |
dist/index.cjs |
Your project is CommonJS. |
| Types | dist/index.d.ts |
Always — same file for both. |
Both are produced from the same source — behavior is identical. Pick whichever matches your project.
ESM:
import { PlugipayClient, verifyWebhook, PlugipayError } from '@forjio/plugipay-node';
CommonJS:
const { PlugipayClient, verifyWebhook, PlugipayError } = require('@forjio/plugipay-node');
Both forms expose exactly the same surface.
"type": "module"is optional. The SDK works the same way in a classic CommonJS project as in a fully-ESM one. Pick what's consistent with the rest of your codebase — don't switch on the SDK's behalf.
TypeScript
The package ships its own .d.ts files — you don't need a separate @types/... install. After npm install, your editor should immediately pick up:
PlugipayClientandPlugipayClientOptions- Every resource input shape (e.g. the argument to
customers.create) - Every resource return type (
Customer,CheckoutSession,Invoice, ...) - The
WebhookEventdiscriminated union PlugipayError
The recommended tsconfig.json settings:
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}
module: "NodeNext" is the safest choice — it picks the right entry (ESM vs CJS) automatically based on your package's "type" field.
Turn on
strict. The SDK types are exhaustive; you'll catch optional-field mistakes (e.g. forgetting thatcustomer.emailcan benull) at compile time rather than at runtime.
Tree-shaking
The SDK is structured as a single PlugipayClient class with all resources as instance properties. Tree-shaking works at the import boundary:
import { PlugipayClient } from '@forjio/plugipay-node';
// `verifyWebhook` and `PlugipayError` are not included in the bundle.
If you only need the webhook verifier (e.g. in a small webhook receiver), import just that:
import { verifyWebhook } from '@forjio/plugipay-node';
// `PlugipayClient` and all resource types are not bundled.
The whole library is under 10 KB minified. Tree-shaking helps marginally; don't optimize prematurely.
Bundling
For server runtimes (raw Node, Fastify, Express, NestJS), no bundling is needed — install and run.
For serverless / edge bundlers (esbuild, swc, webpack, Vercel, AWS Lambda, Cloudflare Workers), a few notes:
- Cloudflare Workers / Deno / Bun edge runtimes. These don't expose
node:crypto. The SDK won't run there. Stick to Node-compatible runtimes (Lambda Node 20 runtime, Vercel Functions Node 20 runtime, Cloud Run, Fly, regular Docker, etc.). - AWS Lambda. Works out of the box on the Node 20 runtime. Don't shim
fetch— use the native one. - esbuild. Set
platform: 'node'andtarget: 'node20'. The SDK doesn't need polyfills. - Webpack. Don't shim
node:crypto. Externalize it or let webpack 5's built-in Node target handle it.
If you see Cannot find module 'node:crypto' at runtime, you're targeting a non-Node runtime. Switch back to a Node-compatible target.
Verifying the install
A one-line smoke test that the package resolved and exports look right:
import { PlugipayClient } from '@forjio/plugipay-node';
console.log(typeof PlugipayClient); // → "function"
To check end-to-end connectivity against your account, see Quickstart.
Upgrading
The SDK follows semantic versioning. For 0.x releases (where we are today), minor bumps may include small breaking changes — each is documented in the changelog.
Pin a caret range and review the changelog before bumping the minor:
{
"dependencies": {
"@forjio/plugipay-node": "^0.5.0"
}
}
After 1.0 (target: mid-2026), the major/minor/patch contract becomes strict and you can rely on ^1.x.x unconditionally.
Troubleshooting
ERR_REQUIRE_ESM
You're using require('@forjio/plugipay-node') from an ESM context, or vice versa. Check your project's "type" field in package.json and use the matching import syntax.
fetch is not defined
You're on Node <18. Upgrade to Node 20+ — the SDK doesn't ship a fetch polyfill.
Cannot find module 'node:crypto'
You're bundling for a non-Node runtime (Cloudflare Workers, browser, Deno edge). The SDK isn't compatible with those. Use a Node-compatible runtime.
TypeScript can't find the types
Make sure your tsconfig.json uses "moduleResolution": "NodeNext" (or "Bundler"). The package's exports field uses conditional resolution, which only works with modern resolvers.
Next
- Quickstart — first end-to-end call.
- Authentication — how to wire up your keys.
- Reference — the full method list.