An opinionated TypeScript framework for building third-party API integrations behind a single, unified data model and interface.
Integrating with external APIs (HR systems, directories, chat platforms, …) usually means learning each provider's bespoke authentication, data shapes and pagination. EasyBREAD hides that complexity behind a small, consistent surface:
- One client, one interface. You talk to every provider through a single
EasyBreadClient.invoke(operation, input)call. - One data model. Inputs and outputs use BreadSchema types derived from the
Schema.org vocabulary, so a
PersonSchemalooks the same whether it came from Google or BambooHR. The raw provider response is always available onrawPayloadwhen you need it. - Auth & multitenancy handled for you. OAuth 2.0 tokens, refresh flows and Basic
auth credentials are stored and replayed transparently, keyed by a
breadIdyou control. A single application can hold many independent connections to the same API. - Pluggable adapters. Service, auth, state and data adapters are interchangeable building blocks, so you can swap storage backends or add new providers without touching application code.
📖 Full documentation lives in the Docusaurus site (see Getting Started and the Mental Model) and on the project Wiki.
Application ──▶ EasyBreadClient ──▶ ServiceAdapter ──▶ External API
│ ▲
│ └── DataAdapter (maps to/from BreadSchema)
└───── AuthStrategy ──▶ StateAdapter (stores AuthData)
Everything you do — including authentication — is expressed as an Operation. The client passes the operation to a ServiceAdapter, which uses an AuthStrategy (backed by a StateAdapter) to authorize the request and a DataAdapter to map between the unified schema and the provider's format.
pnpm add @easybread/core @easybread/schemas @easybread/commands
# then add the service adapter(s) you need, e.g.:
pnpm add @easybread/adapter-google-common @easybread/adapter-google-admin-directoryimport { EasyBreadClient, InMemoryStateAdapter } from '@easybread/core';
import {
GoogleAdminDirectoryAdapter,
GoogleAdminDirectoryAuthStrategy,
GoogleAdminDirectoryOperationName,
} from '@easybread/adapter-google-admin-directory';
const stateAdapter = new InMemoryStateAdapter();
const authStrategy = new GoogleAdminDirectoryAuthStrategy(stateAdapter, {
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
redirectUri: process.env.GOOGLE_REDIRECT_URI!,
});
const serviceAdapter = new GoogleAdminDirectoryAdapter(authStrategy);
const client = new EasyBreadClient(stateAdapter, serviceAdapter);
const { payload } = await client.invoke(
GoogleAdminDirectoryOperationName.USERS_SEARCH,
{ breadId: 'tenant-1', params: { query: 'jane' } },
);See the Getting Started guide for the full authentication walkthrough.
This repository is an Nx + pnpm monorepo. The
published libraries live under packages/:
| Package | Description |
|---|---|
@easybread/core |
The EasyBreadClient, operation executor, base adapter classes and the built-in InMemoryStateAdapter. |
@easybread/commands |
Canonical BREAD_COMMAND_NAME operation catalog and command/output types shared by every adapter. |
@easybread/schemas |
The Schema.org-derived BreadSchema types (e.g. PersonSchema) used for all operation inputs and outputs. |
@easybread/common |
Low-level type helpers and enum utilities (enumPickKeys, enumMerge, …) used across the codebase. |
| Package | Description |
|---|---|
@easybread/data-adapter |
breadDataAdapter — declarative two-way mapping between external and internal data shapes. |
@easybread/data-mapper |
The lower-level property-mapping engine that powers the data adapter. |
@easybread/pagination-adapter |
Normalizes provider-specific pagination into the unified PREV_NEXT / OFFSET models. |
| Package | Description |
|---|---|
@easybread/state-adapter-mongo |
MongoDB-backed StateAdapter for persisting auth data outside of memory. |
| Package | Provider | Operations |
|---|---|---|
@easybread/adapter-bamboo-hr |
BambooHR | Basic / OpenID Connect auth, employee BREAD, job application & applicant search |
@easybread/adapter-breezy |
Breezy HR | Basic auth, organization search, job applicant search |
@easybread/adapter-google-common |
Shared Google OAuth 2.0 auth flow used by the Google adapters | |
@easybread/adapter-google-admin-directory |
Google Admin Directory | OAuth 2.0 auth, user BREAD operations |
@easybread/adapter-google-contacts |
Google Contacts | OAuth 2.0 auth, contact BREAD operations |
@easybread/adapter-rocket-chat-common |
Rocket.Chat | Shared Rocket.Chat Basic auth |
@easybread/adapter-rocket-chat-users |
Rocket.Chat | Basic auth, user search & lookup |
| Package | Description |
|---|---|
@easybread/test-utils |
Shared testing helpers (not published). |
apps/saas— a Next.js + tRPC SaaS reference application built on top of EasyBREAD.playground— a sandbox app for exercising the adapters locally.docs/easybread/app— the Docusaurus documentation site.
This repo uses pnpm (pinned via the packageManager field) and Nx.
pnpm install # install dependencies
pnpm local:up # start local services (docker compose)
pnpm local:down # stop local services
# Nx targets (run for one project or with run-many / affected)
pnpm exec nx run-many -t build # build all packages
pnpm exec nx run-many -t test # run all unit tests
pnpm exec nx run-many -t lint # lint everything
pnpm exec nx test @easybread/core # target a single projectReleases are managed with pnpm bump (nx release) and published from CI on tag pushes.
Issues and pull requests are welcome. Please run lint, build and test for the
projects you touch before opening a PR — CI runs the same targets via nx affected.