Skip to content

fix(sdk): keep per-API imports from pulling every API's docs into a bundle - #604

Merged
alexmarqs merged 1 commit into
mainfrom
fix/sdk-per-api-lazy-docs
Nov 13, 2026
Merged

alexmarqs merged 1 commit into
mainfrom
fix/sdk-per-api-lazy-docs

Conversation

@alexmarqs

Copy link
Copy Markdown
Member

Problem

Importing a single client, e.g. @epilot/sdk/pricing, makes a bundler emit a lazy chunk for the docs and OpenAPI spec of every API in the SDK: about 160 chunks, 5 MiB of build output.

client.help() and client.openapi() look their files up by name (import(./docs/${name})). esbuild turns that into a glob map of every doc and definition, and that map sat in the chunk all @epilot/sdk/<api> entries share. The chunks only load if those methods are called, so users don't download them, but they bloat every consumer's build. Present in every version sampled from 2.5.0 to 2.20.106.

Fix

Each @epilot/sdk/<api> entry now passes loaders with literal paths to its own two files (src/api-docs.ts, lazyApiDocs). client-factory no longer imports the by-name lookup; that stays for the root SDK only (epilot.help(name), epilot.openapi(name), and the help/openapi exports).

  • help() and openapi() behave as before on per-API clients and on the root SDK.
  • The 56 files in src/apis/ are regenerated from the updated template in scripts/generate-sdk-v2.ts.
  • src/apis/target.ts has no client behind it any more (the API is targeting) but is still built, so it is updated by hand to keep the build passing.

Measured

Same SDK version (2.20.106) built without and with the fix, dropped into two consumers' installed SDK, production webpack builds:

App Unfixed Fixed SDK docs/spec chunks
Journey builder (1 API, via @epilot/address-suggestion) 11.65 MiB 7.00 MiB 162 → 2
Integration hub (11 APIs) 21.30 MiB 17.48 MiB 162 → 19

Initial JS is unchanged in both (these chunks were never loaded).

Tests

  • pnpm lint and pnpm test pass (368 tests).
  • New in dist-integration.test.ts: every per-API dist entry may reach at most its own two lazy files; a per-API client still serves help() and openapi() from the built package.

Notes

  • 11 APIs (calendar, chat, identity, …) have no full spec checked into src/definitions, so openapi() already failed for them. It now throws No OpenAPI specification bundled for "<api>" instead of a module-not-found error. Not addressed here.
  • Changeset included (patch).

🤖 Generated with Claude Code

…undle

Importing one client, e.g. @epilot/sdk/pricing, made bundlers emit a lazy
chunk for the docs and OpenAPI spec of every API (about 160 chunks, 5 MiB).
client.help() and client.openapi() looked their files up by name through a
glob import that lived in the chunk every per-API entry shares.

Each @epilot/sdk/<api> entry now passes loaders with literal paths to its
own two files. The by-name lookup stays for the root SDK only. help() and
openapi() behave as before.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>

@anttiviljami anttiviljami left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one! Thanks @alexmarqs !

@alexmarqs
alexmarqs merged commit 79df4b1 into main Nov 13, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants