Skip to content

feat(package): expose subpath exports for lighter consumer imports#238

Open
tsushanth wants to merge 1 commit into
square:masterfrom
tsushanth:feat/subpath-exports
Open

feat(package): expose subpath exports for lighter consumer imports#238
tsushanth wants to merge 1 commit into
square:masterfrom
tsushanth:feat/subpath-exports

Conversation

@tsushanth

Copy link
Copy Markdown

Closes #237.

The problem

The default import { SquareClient } from 'square' entry transitively loads every API resource client, every Fern-generated type module, and the ~1,300 runtime serialization schemas under serialization/types/. On boot-sensitive workloads (serverless cold starts, autoscaling instances) the total dominates startup time — the issue reporter measured ~600 ms just from require('square') on an M3 MacBook Air, with serialization/index.js alone accounting for 12 % of the boot path.

The SDK's surface is already split across small directories at the package root after prepack copies dist/. over (./api/, ./serialization/, ./Client.js, ./environments.js, ./errors/), but the exports map only publishes . and ./legacy, so consumers who want to opt out can't reach the internal modules through a supported path.

The change

Add subpath entries — each with a types mapping so TypeScript's nodenext / bundler resolvers find the declarations — that let consumers import only the slice they need:

// Just the type definitions for a single resource — no runtime schemas loaded.
import type { Payment } from 'square/api/types/Payment';

// Just one resource client.
import { PaymentsClient } from 'square/api/resources/payments';

// Just the runtime serialization for a single model.
import { Payment as PaymentSchema } from 'square/serialization/types/Payment';

// Just the SDK entry-point class and constants.
import { SquareClient } from 'square/Client';
import { SquareEnvironment } from 'square/environments';

The default import { SquareClient } from 'square' entry is unchanged and remains the recommended import for typical usage — the new entries are strictly additive, no existing call site changes shape.

README gets a short ### Subpath imports subsection under ## Usage pointing at the new import paths and the cold-start motivation, so the next person reading the docs after a wiz / lighthouse / cold-start profile knows the supported escape hatch.

What this doesn't do

This doesn't make the default square entry itself faster — the eager re-exports in src/index.ts and the Fern-generated cascade still pull in everything. That looks like a separate (and bigger) discussion about how the generator structures the umbrella module; happy to follow up there if there's appetite.

Closes square#237.

The default `import { SquareClient } from 'square'` entry transitively
loads every API resource client, every Fern-generated type module, and
the ~1,300 runtime serialization schemas under `serialization/types/`.
On boot-sensitive workloads (serverless cold starts, autoscaling), the
total dominates startup time — the reporter measured ~600 ms just from
the require on an M3 MacBook Air, with `serialization/index.js` alone
accounting for 12 % of the boot path.

The SDK's surface is already split across small directories at the
package root after `prepack` copies `dist/.` over — `./api/`,
`./serialization/`, `./Client.js`, `./environments.js`, `./errors/` —
but the `exports` map only published `.` and `./legacy`, so consumers
who wanted to opt out couldn't reach the internal modules through a
supported path. Adding subpath entries (with `types` mappings so
TypeScript's nodenext / bundler resolvers find the declarations)
lets them import only the slice they need:

```ts
import type { Payment } from 'square/api/types/Payment';
import { PaymentsClient } from 'square/api/resources/payments';
import { Payment as PaymentSchema } from 'square/serialization/types/Payment';
import { SquareClient } from 'square/Client';
```

The default `import { SquareClient } from 'square'` entry is unchanged
and remains the recommended import for typical usage; the new entries
are strictly additive.

README gets a short subsection under "Usage" pointing at the new
import paths and the cold-start motivation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

SDK is extremely heavy to import

1 participant