Skip to content

Getting started ​

Install ​

bash
npm install breeze-client

One package, one tag. If you are used to choosing between breeze-client, breeze-client@cjs and breeze-client@mjs, that is gone — there is only latest.

Requirements: Node 20+ for server-side or test use, and any browser with native fetch. Breeze 3 ships ES modules only, so you will be using a bundler (Vite, webpack, esbuild, Rollup) or native import. There is no UMD bundle and no <script> tag build.

TypeScript 4.1 or later. The typings use template literal types, which arrived in 4.1; an older compiler cannot parse them at all.

A bundler that reads ES2022. The published JavaScript uses class fields, so the parser has to understand them: webpack 5, Vite, Rollup and esbuild all do. webpack 4 does not, which in practice means Angular 11 and earlier cannot bundle Breeze 3 without transpiling the package down a level first.

Configure ​

With a Breeze .NET server there is nothing to configure. Go straight to creating an EntityManager.

There are no adapters to import or register. Unless you say otherwise, Breeze talks to a Breeze .NET server, encodes queries as Breeze JSON, tracks changes with plain properties, makes its HTTP requests with the platform's fetch, and camel-cases property names: CompanyName on the server is companyName on the client. To replace any of those, see Configuration; to add auth headers or logging, see Supplying your own transport.

If your server already sends the property names the client should use — a Node server, say, or one whose names are already camelCase — turn the translation off. Do it once, at startup, before you create any EntityManager:

ts
import { configureBreeze, NamingConvention } from 'breeze-client';

configureBreeze({ namingConvention: NamingConvention.none });

NamingConvention.none.setAsDefault() does the same thing. See Naming conventions.

Create an EntityManager ​

An EntityManager is a cache plus a connection to one service. Most applications have one.

ts
import { EntityManager } from 'breeze-client';

const em = new EntityManager('/breeze/NorthwindIBModel');

The string is the service root. Breeze fetches metadata from /breeze/NorthwindIBModel/Metadata the first time you query, and uses it to build entity types, keys and relationships.

Give Breeze your entity classes ​

Optional, but it is what makes everything below type-checked, so it is worth two lines now. Write a class per entity type and register it:

ts
import { EntityBase } from 'breeze-client';

// EntityBase declares the members Breeze supplies: entityAspect, entityType and the rest.
export class Customer extends EntityBase {
  declare customerID: string;
  declare companyName: string;
  declare orders: Order[];
}

em.metadataStore.registerEntityTypeCtor('Customer', Customer);

You don't have to write these by hand — Breeze ships a generator that produces one file per type from your service's metadata. See Generating entity classes, and Typed entities for what registering them buys you.

Skip this and everything still works; you reach properties through getProperty('companyName') instead, and results come back as any. The rest of this page shows both.

Query ​

ts
import { EntityQuery } from 'breeze-client';

const query = EntityQuery
  .from(Customer)                      // resource name comes from the metadata
  .where('companyName', 'startsWith', 'B')
  .orderBy('companyName')
  .take(10);

const { results } = await em.executeQuery(query);   // results: Customer[]

results.forEach(c => console.log(c.companyName));

Without classes, name the resource and reach for properties by name:

ts
const query = EntityQuery.from(Customer).where('companyName', 'startsWith', 'B');
const { results } = await em.executeQuery(query);   // results: any[]

results.forEach(c => console.log(c.getProperty('companyName')));

Results are entities, not plain objects: they are in the cache, they track their own changes, and their navigation properties are wired to other cached entities.

See Querying for the full query surface.

Change and save ​

ts
const customer = results[0];
customer.companyName = 'Bravo Foods';       // or customer.setProperty('companyName', …)

console.log(customer.entityAspect.entityState.name);  // "Modified"

const saveResult = await em.saveChanges();
console.log(`${saveResult.entities.length} entities saved`);

saveChanges() sends every pending change in one request, and the server applies them in one transaction. You can also save a subset — see Saving changes.

Create a new entity ​

ts
const order = em.createEntity(Order, {
  customerID: customer.customerID,
  orderDate: new Date(),
});

await em.saveChanges();

createEntity gives the new entity a temporary key, adds it to the cache, and marks it Added. On save, the server assigns the real key and Breeze fixes up every reference to it.

Where next ​

  • Configuration — the default adapters, replacing them, and supplying your own HTTP transport
  • Querying — predicates, projections, expand, querying the cache
  • Inside the entity — entityAspect, entity state, original values
  • Migrating from 2.x — if you have an existing application

Released under the MIT License.