@cocartheadless/sdk

Official TypeScript SDK for the CoCart REST API. Build headless WooCommerce storefronts β meaning your frontend (React, Astro, Next.js, or any framework) talks to WooCommerce through its API instead of using PHP templates.
[!IMPORTANT]
This SDK is looking for feedback, if you experience a bug please report it.
TODO to complete the SDK
Requirements
- Node.js 20+ β Node.js is the JavaScript runtime that lets you run JavaScript outside a browser (e.g., on a server). Version 20 or higher is required because it includes a built-in
fetch function for making HTTP requests. You can check your version by running node -v in your terminal.
- CoCart plugin installed on your WooCommerce store β This is the WordPress plugin that provides the REST API endpoints the SDK communicates with.
- CoCart JWT Authentication plugin for JWT features (optional) β Only needed if you want to use JSON Web Token authentication (explained in the Authentication guide).
- TypeScript 5.0+ (recommended) β Not strictly required, but you get the best experience (autocompletion, type checking) with TypeScript.
Support Policy
See SUPPORT.md for our versioning policy, supported Node.js versions, and support lifecycle.
Features
- Zero runtime dependencies β uses native
fetch (Node 20+, all modern browsers), no extra packages to install
- ESM + CJS dual output β works with both modern
import syntax and older require() syntax
- Typed responses and parameters with generics
- Client-side input validation (catches errors before network requests)
- Currency formatting and timezone utilities
- Event system for request/response lifecycle hooks
- Response transformer for custom processing
- Configurable auth header name (for proxies that strip
Authorization)
- Encrypted localStorage for session persistence (AES-256-GCM, Web Crypto API)
- JWT authentication with auto-refresh
- Legacy CoCart plugin support with version-aware endpoint guards
- Framework adapters for Astro, Next.js, Nuxt, Remix, SvelteKit, Vite, Elysia.js, Fastify, Hono, and Deno
Installation
Via npm
npm is the default package manager that comes with Node.js. Run this in your project's root folder:
npm install @cocartheadless/sdk
Via yarn
Yarn is an alternative package manager. If you use Yarn in your project:
yarn add @cocartheadless/sdk
Via pnpm
pnpm is a fast, disk-efficient package manager. If you use pnpm:
pnpm add @cocartheadless/sdk
Via Bun
Bun is a fast JavaScript runtime with a built-in package manager. If you use Bun:
bun add @cocartheadless/sdk
Zero runtime dependencies β the SDK does not install any additional packages, keeping your project lightweight.
Via CDN (Framer, Webflow, plain HTML)
For platforms like Framer, Webflow, or any environment where you just need a <script> tag β no npm required:
jsDelivr:
<script src="https://cdn.jsdelivr.net/npm/@cocartheadless/sdk/dist/index.global.js"></script>
unpkg:
<script src="https://unpkg.com/@cocartheadless/sdk/dist/index.global.js"></script>
Then use it:
<script>
const client = new CoCart('https://your-store.com');
</script>
This loads a single minified file that exposes all SDK exports under the CoCart global. See the dedicated guides for Framer and Webflow.
You can also pin a specific version:
<script src="https://cdn.jsdelivr.net/npm/@cocartheadless/sdk@1.1.0/dist/index.global.js"></script>
<script src="https://unpkg.com/@cocartheadless/sdk@1.1.0/dist/index.global.js"></script>
Quick Start
An SDK (Software Development Kit) is a library that provides ready-made functions for talking to a specific service β in this case, the CoCart REST API on your WooCommerce store. Instead of writing raw HTTP requests yourself, you call simple methods like client.cart().addItem(123, 2) and the SDK handles the details for you.
The import statement loads the SDK into your code. The await keyword is used before operations that talk to the server, because network requests take time and JavaScript needs to wait for the response before continuing.
import { CoCart } from '@cocartheadless/sdk';
const client = new CoCart('https://your-store.com');
const products = await client.products().all({ per_page: '12' });
const response = await client.cart().addItem(123, 2);
const cart = await client.cart().get();
console.log(cart.getItems());
console.log(cart.get('totals.total'));
Note: Code using await must be inside an async function. If you're using a modern framework like Next.js, Astro, or Nuxt, your component or page functions are already async. In a plain script, wrap your code in an async function:
async function main() {
const client = new CoCart('https://your-store.com');
const cart = await client.cart().get();
console.log(cart.getItems());
}
main();
Documentation
| Configuration & Setup | Options, fluent config, framework adapters, white-labelling |
| Authentication | Guest, Basic Auth, JWT, consumer keys |
| Cart API | Add, update, remove items, coupons, shipping, fees |
| Products API | List, filter, search, categories, tags, brands |
| Sessions API | Admin sessions, SessionManager, storage adapters |
| Error Handling | Error hierarchy, catching errors, common scenarios |
| Utilities | Currency formatter, timezone helper, response transformer |
Framework Adapters
| Astro | Browser + SSR setup, API routes, examples |
| Next.js | Client + Server Components, Route Handlers, middleware |
| Nuxt | Browser plugin, server routes, defineEventHandler |
| Remix | Loaders, actions, resource routes |
| SvelteKit | load functions, server routes, hooks |
| Vite | Browser-only SPA; pair with a backend adapter for the API layer |
| Elysia.js | Bun-first route handlers |
| Fastify | Node.js route handlers (server-only) |
| Hono | Multi-runtime (Node, Bun, Cloudflare Workers, Deno) |
| Deno | Deno.serve(), Fresh islands |
| Framer | CDN script, Code Overrides, product display |
| Webflow | CDN script, custom code, dynamic elements |
Features
Fluent API
A fluent API lets you chain multiple calls in a single expression instead of writing separate statements. Each method returns the client itself, so you can keep adding dots:
const client = new CoCart('https://your-store.com')
.setTimeout(15000)
.setMaxRetries(2)
.addHeader('X-Custom', 'value');
Dot-Notation Response Access
Access nested data in API responses using a simple string path with dots β no need to chain object properties or worry about undefined errors:
const cart = await client.cart().get();
cart.get('totals.total');
cart.get('currency.currency_code');
cart.get('items.0.name');
Type-Safe Field Filtering
Request only the fields you need β the return type narrows automatically:
const response = await client.cart().getFiltered(['items', 'totals']);
const data = response.toObject();
data.items;
data.totals;
data.currency;
Currency Formatting
import { CurrencyFormatter } from '@cocartheadless/sdk';
const fmt = new CurrencyFormatter();
const currency = response.getCurrency();
fmt.format(4599, currency);
fmt.formatDecimal(4599, currency);
Client-Side Validation
Invalid inputs are caught before making a network request:
await client.cart().addItem(-1, 0);
Event System
client.on('request', (e) => console.log(`${e.method} ${e.url}`));
client.on('response', (e) => console.log(`${e.status} in ${e.duration}ms`));
client.on('error', (e) => console.error(e.error));
Encrypted Session Storage
Cart keys and tokens are stored in the browser's localStorage encrypted with AES-256-GCM via the Web Crypto API β a browser-native encryption API that requires no extra libraries:
import { CoCart, EncryptedStorage } from '@cocartheadless/sdk';
const storage = new EncryptedStorage('your-secret-key');
const client = new CoCart('https://your-store.com', { storage });
JWT with Auto-Refresh
JWT (JSON Web Token) is a secure authentication method where you log in once and receive a token. The SDK can automatically refresh expired tokens behind the scenes, so customers never get unexpectedly logged out:
const result = await client.jwt().withAutoRefresh(async (c) => {
return await c.cart().get();
});
Framework Adapters (No Cookies)
Pre-built adapters for Astro, Next.js, Nuxt, Remix, SvelteKit, Elysia.js, Fastify, Hono, and Deno handle the browser/server split automatically. Cart state is passed via HTTP headers instead of cookies β avoiding GDPR consent issues and CORS restrictions:
import { createBrowserClient, attachCartKeyHeader } from '@cocartheadless/sdk/astro';
const client = createBrowserClient('https://your-store.com', {
encryptionKey: 'your-key',
});
await client.restoreSession();
attachCartKeyHeader(client);
import { createServerClient } from '@cocartheadless/sdk/astro';
const client = createServerClient('https://your-store.com', Astro.request);
CoCart Channels
We have different channels at your disposal where you can find information about the CoCart project, discuss it and get involved:

- π Documentation: this is the place to learn how to use CoCart API. Get started!
- πͺ Community: use our Discord chat room to share any doubts, feedback and meet great people. This is your place too to share how are you planning to use CoCart!
- π GitHub: we use GitHub for bugs and pull requests, doubts are solved with the community.
- π¦ Social media: a more informal place to interact with CoCart users, reach out to us on X/Twitter.
Credits
Website cocartapi.com Β Β·Β
GitHub @cocart-headless Β Β·Β
X/Twitter @cocartapi Β Β·Β
Facebook Β Β·Β
Instagram
License
MIT