agentsys 5.3.7 → 5.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/.agnix.toml +17 -7
  2. package/.claude-plugin/marketplace.json +13 -2
  3. package/.claude-plugin/plugin.json +1 -1
  4. package/.gitmodules +3 -0
  5. package/AGENTS.md +4 -4
  6. package/CHANGELOG.md +21 -0
  7. package/README.md +46 -5
  8. package/lib/adapter-transforms.js +3 -1
  9. package/package.json +1 -1
  10. package/site/assets/css/main.css +39 -1
  11. package/site/assets/js/main.js +24 -0
  12. package/site/content.json +4 -4
  13. package/site/index.html +82 -7
  14. package/site/ux-spec.md +5 -5
  15. package/agent-knowledge/AGENTS.md +0 -231
  16. package/agent-knowledge/acp-with-codex-gemini-copilot-claude.md +0 -504
  17. package/agent-knowledge/ai-cli-advanced-integration-patterns.md +0 -670
  18. package/agent-knowledge/ai-cli-non-interactive-programmatic-usage.md +0 -1394
  19. package/agent-knowledge/all-in-one-plus-modular-packages.md +0 -576
  20. package/agent-knowledge/cli-browser-automation-agents.md +0 -936
  21. package/agent-knowledge/github-org-project-management.md +0 -319
  22. package/agent-knowledge/github-org-structure-patterns.md +0 -268
  23. package/agent-knowledge/kiro-supervised-autopilot.md +0 -400
  24. package/agent-knowledge/multi-product-org-docs.md +0 -622
  25. package/agent-knowledge/oss-org-naming-patterns.md +0 -368
  26. package/agent-knowledge/resources/acp-with-codex-gemini-copilot-claude-sources.json +0 -408
  27. package/agent-knowledge/resources/ai-cli-non-interactive-programmatic-usage-sources.json +0 -500
  28. package/agent-knowledge/resources/all-in-one-plus-modular-packages-sources.json +0 -310
  29. package/agent-knowledge/resources/cli-browser-automation-agents-sources.json +0 -428
  30. package/agent-knowledge/resources/github-org-project-management-sources.json +0 -239
  31. package/agent-knowledge/resources/github-org-structure-patterns-sources.json +0 -293
  32. package/agent-knowledge/resources/kiro-supervised-autopilot-sources.json +0 -135
  33. package/agent-knowledge/resources/multi-product-org-docs-sources.json +0 -514
  34. package/agent-knowledge/resources/oss-org-naming-patterns-sources.json +0 -458
  35. package/agent-knowledge/resources/skill-plugin-distribution-patterns-sources.json +0 -290
  36. package/agent-knowledge/resources/terminal-browsers-agent-automation-sources.json +0 -758
  37. package/agent-knowledge/resources/web-session-persistence-cli-agents-sources.json +0 -528
  38. package/agent-knowledge/skill-plugin-distribution-patterns.md +0 -661
  39. package/agent-knowledge/terminal-browsers-agent-automation.md +0 -776
  40. package/agent-knowledge/web-session-persistence-cli-agents.md +0 -1352
@@ -1,576 +0,0 @@
1
- # Learning Guide: All-in-One Plus Modular Packages
2
-
3
- **Generated**: 2026-02-21
4
- **Sources**: 40 resources analyzed
5
- **Depth**: deep
6
-
7
- ## Prerequisites
8
-
9
- - Familiarity with package managers (npm, pip, cargo, etc.)
10
- - Basic understanding of monorepos vs polyrepos
11
- - Experience publishing or consuming packages from a registry
12
- - Understanding of semantic versioning (semver)
13
-
14
- ## TL;DR
15
-
16
- - The "batteries included but removable" pattern provides a meta-package that re-exports or depends on individual modular packages, letting users choose convenience OR minimal footprint.
17
- - Monorepo tooling (npm/pnpm/yarn workspaces, Lerna, Nx, Turborepo, Rush, Changesets) makes it practical to develop, version, and publish dozens of packages from a single repository.
18
- - Real-world examples span a spectrum: lodash (per-method packages), AWS SDK v3 (@aws-sdk/client-*), Babel (@babel/plugin-*), Angular (@angular/*), Effect (@effect/*), and more.
19
- - Installer CLIs (create-react-app, degit/tiged, npx-based scaffolders) fetch templates from registries or GitHub tarballs, not git clones.
20
- - Version pinning strategies include lockfiles, changesets, fixed vs independent versioning, and workspace protocol references.
21
-
22
- ## Core Concepts
23
-
24
- ### 1. The Packaging Spectrum
25
-
26
- Open source projects sit on a spectrum from fully monolithic to fully granular:
27
-
28
- | Model | Example | Trade-off |
29
- |-------|---------|-----------|
30
- | **Monolithic** | lodash (full), aws-sdk v2 | Simple to adopt, large bundle |
31
- | **Scoped modular** | @aws-sdk/client-s3, @babel/plugin-* | Tree-shakeable, more install commands |
32
- | **Per-function** | lodash.get, lodash.debounce | Minimal footprint, dependency explosion |
33
- | **Core + plugins** | ESLint, webpack, Vite, Pino | Extensible, requires configuration |
34
- | **Meta-package** | jest (wraps @jest/*), Angular | Convenience layer over modular internals |
35
-
36
- **Key insight**: Most successful projects offer BOTH a convenience meta-package AND individual packages. Users choose based on their constraints.
37
-
38
- ### 2. The Meta-Package Pattern
39
-
40
- A meta-package is a thin wrapper that re-exports or depends on individual packages:
41
-
42
- ```json
43
- {
44
- "name": "my-framework",
45
- "version": "3.0.0",
46
- "dependencies": {
47
- "@my-framework/core": "3.0.0",
48
- "@my-framework/router": "3.0.0",
49
- "@my-framework/cli": "3.0.0",
50
- "@my-framework/utils": "3.0.0"
51
- }
52
- }
53
- ```
54
-
55
- The meta-package `index.js` re-exports everything:
56
-
57
- ```javascript
58
- // my-framework/index.js
59
- export { createApp, defineComponent } from '@my-framework/core';
60
- export { createRouter, useRoute } from '@my-framework/router';
61
- export { cli } from '@my-framework/cli';
62
- ```
63
-
64
- Users can install `my-framework` for everything, or `@my-framework/core` alone for minimal footprint.
65
-
66
- **Real-world examples**:
67
- - **Jest**: `jest` meta-package wraps `@jest/core`, `@jest/expect`, `@jest/globals`, etc.
68
- - **Angular**: `@angular/core`, `@angular/router`, `@angular/forms` are independent but `ng new` installs them together.
69
- - **Effect**: Core `effect` package plus 20+ `@effect/*` packages for platform, SQL, AI, RPC, etc.
70
- - **Astro**: Core `astro` plus `@astrojs/react`, `@astrojs/vue`, `@astrojs/node`, `@astrojs/vercel`, etc.
71
-
72
- ### 3. Monorepo Tooling for Multi-Package Projects
73
-
74
- Publishing multiple packages from one repo requires specialized tooling:
75
-
76
- #### Workspace Managers (dependency linking)
77
-
78
- | Tool | Workspace Config | Key Feature |
79
- |------|-----------------|-------------|
80
- | **npm workspaces** | `package.json#workspaces` | Built into npm 7+ |
81
- | **pnpm workspaces** | `pnpm-workspace.yaml` | Content-addressable storage, strict isolation |
82
- | **yarn workspaces** | `package.json#workspaces` | Plug'n'Play resolution, zero-installs |
83
- | **bun workspaces** | `package.json#workspaces` | Native speed, compatible with npm |
84
-
85
- #### Build Orchestrators (task scheduling)
86
-
87
- | Tool | Written In | Key Feature |
88
- |------|-----------|-------------|
89
- | **Turborepo** | Rust | Remote caching, task pipelines |
90
- | **Nx** | TypeScript | Affected analysis, computation caching |
91
- | **Rush** | TypeScript | Enterprise-scale, strict dependency policies |
92
- | **Lerna** | TypeScript | Version/publish commands, now maintained by Nx |
93
-
94
- #### Version & Publish Managers
95
-
96
- | Tool | Approach | Best For |
97
- |------|----------|----------|
98
- | **Changesets** | Intent-based changelogs | Monorepos with multiple maintainers |
99
- | **Lerna version/publish** | Conventional commits or manual | Established monorepos |
100
- | **semantic-release** | Fully automated from commits | Single packages or coordinated releases |
101
- | **np** | Interactive guided publish | Single package publishing |
102
-
103
- ### 4. Versioning Strategies
104
-
105
- #### Fixed (Locked) Versioning
106
-
107
- All packages share one version number. When any package changes, all bump together.
108
-
109
- ```json
110
- // lerna.json
111
- {
112
- "version": "3.2.1"
113
- }
114
- ```
115
-
116
- **Used by**: Babel, Angular, React (within a release)
117
- **Pro**: Simple mental model -- all `@babel/*` packages at 7.24.0 are compatible.
118
- **Con**: Unnecessary version bumps for unchanged packages.
119
-
120
- #### Independent Versioning
121
-
122
- Each package has its own version. Only changed packages bump.
123
-
124
- ```json
125
- // lerna.json
126
- {
127
- "version": "independent"
128
- }
129
- ```
130
-
131
- **Used by**: AWS SDK v3, Effect, Astro integrations
132
- **Pro**: Precise, no unnecessary bumps.
133
- **Con**: Harder to know which versions are compatible.
134
-
135
- #### Workspace Protocol
136
-
137
- pnpm and yarn support `workspace:*` to reference sibling packages during development, resolved to actual versions at publish time:
138
-
139
- ```json
140
- {
141
- "dependencies": {
142
- "@my-lib/utils": "workspace:*"
143
- }
144
- }
145
- ```
146
-
147
- At publish time, `workspace:*` becomes `^3.2.1` (the actual version). This prevents accidentally publishing with unresolvable local references.
148
-
149
- #### Peer Dependencies for Plugin Compatibility
150
-
151
- Plugins declare their host as a peer dependency to ensure version compatibility:
152
-
153
- ```json
154
- {
155
- "name": "@babel/plugin-transform-classes",
156
- "peerDependencies": {
157
- "@babel/core": "^7.0.0"
158
- }
159
- }
160
- ```
161
-
162
- ### 5. The AWS SDK v2 to v3 Migration (Case Study)
163
-
164
- AWS SDK v2 was a single `aws-sdk` package containing every AWS service client. Problems:
165
- - Bundle size was enormous even if you used one service
166
- - No tree-shaking possible
167
- - Cold start penalties in Lambda
168
-
169
- AWS SDK v3 introduced modular clients:
170
-
171
- ```javascript
172
- // v2: monolithic
173
- const AWS = require('aws-sdk');
174
- const s3 = new AWS.S3();
175
-
176
- // v3: modular
177
- const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');
178
- const s3 = new S3Client({});
179
- ```
180
-
181
- **Architecture changes**:
182
- - Each service is a separate npm package (`@aws-sdk/client-s3`, `@aws-sdk/client-dynamodb`, etc.)
183
- - Middleware stack replaces the monolithic plugin system
184
- - Shared packages like `@aws-sdk/middleware-retry` are consumed by individual clients
185
- - Tree-shaking dramatically reduces bundle size
186
-
187
- ### 6. Lodash: Per-Method Packages (Case Study)
188
-
189
- Lodash offered the most granular packaging approach in npm history:
190
-
191
- | Package | Size | Contents |
192
- |---------|------|----------|
193
- | `lodash` | ~24 kB gzipped | Full library, 300+ methods |
194
- | `lodash-es` | ~24 kB | ES module version (tree-shakeable) |
195
- | `lodash/fp` | ~24 kB | Functional programming variant |
196
- | `lodash.get` | ~1 kB | Single method package |
197
- | `lodash.debounce` | ~1 kB | Single method package |
198
-
199
- **Lessons learned**: Per-method packages caused dependency management headaches -- projects could end up with different versions of lodash internals. The ecosystem eventually moved toward ES modules + tree-shaking as a better solution than per-function packages.
200
-
201
- ### 7. Core + Plugin Architecture
202
-
203
- Many tools use a minimal core with an extensible plugin system:
204
-
205
- **Babel**: `@babel/core` provides the transformation engine. Plugins (`@babel/plugin-transform-*`) handle specific syntax transforms. Presets (`@babel/preset-env`) bundle common plugin sets.
206
-
207
- **ESLint**: Core `eslint` handles linting orchestration. Rules come from plugins (`@eslint/js`, `eslint-plugin-react`). Configs bundle rules into shareable sets.
208
-
209
- **Webpack**: Core `webpack` provides module bundling. Loaders preprocess files (TypeScript, CSS). Plugins hook into the build lifecycle.
210
-
211
- **Vite**: Core `vite` handles dev server and building. Official plugins like `@vitejs/plugin-legacy` extend capabilities.
212
-
213
- **Pino**: Core `pino` does fast JSON logging. `pino-pretty` provides dev formatting. Transports are separate packages run in worker threads.
214
-
215
- **Tailwind CSS**: Core `tailwindcss` provides utility classes. Plugins like `@tailwindcss/typography` and `@tailwindcss/forms` add specialized utilities.
216
-
217
- ### 8. Installer CLI Patterns
218
-
219
- Installer CLIs scaffold projects without requiring global installation:
220
-
221
- #### npx-Based Scaffolders
222
-
223
- ```bash
224
- npx create-react-app my-app # Deprecated but iconic pattern
225
- npx create-next-app my-app # Next.js scaffolder
226
- npx create-astro # Astro scaffolder
227
- npx create-nx-workspace # Nx workspace scaffolder
228
- ```
229
-
230
- How it works under the hood:
231
- 1. `npx` downloads the package temporarily from npm registry
232
- 2. Package exposes a `bin` entry in package.json
233
- 3. Binary runs, prompts user for options
234
- 4. Generates files from templates (embedded or fetched)
235
- 5. Runs `npm install` in the new directory
236
- 6. Temporary package is cleaned up
237
-
238
- #### Template Cloners (degit/tiged)
239
-
240
- ```bash
241
- npx degit user/repo my-project
242
- npx tiged user/repo my-project # Actively maintained fork
243
- ```
244
-
245
- How it works:
246
- 1. Resolves the latest commit on the default branch
247
- 2. Downloads the tar archive from GitHub/GitLab API (NOT git clone)
248
- 3. Caches tarball locally (`~/.degit/user/repo/hash.tar.gz`)
249
- 4. Extracts to target directory
250
- 5. No `.git` directory -- clean copy
251
-
252
- **Advantages over git clone**: No git history, faster download, works offline from cache, supports subdirectory extraction.
253
-
254
- #### Custom CLI Installers
255
-
256
- For tools like `agentsys install web-ctl`, the typical architecture:
257
-
258
- ```javascript
259
- // 1. Parse the install command
260
- const packageName = args[0]; // "web-ctl"
261
-
262
- // 2. Resolve package location (multiple strategies)
263
- async function resolve(name) {
264
- // Strategy A: npm registry
265
- const pkg = await fetch(`https://registry.npmjs.org/${name}/latest`);
266
-
267
- // Strategy B: GitHub releases
268
- const release = await fetch(
269
- `https://api.github.com/repos/org/${name}/releases/latest`
270
- );
271
- const asset = release.assets.find(a => a.name.endsWith('.tar.gz'));
272
-
273
- // Strategy C: Custom registry
274
- const manifest = await fetch(`https://my-registry.dev/${name}/manifest.json`);
275
-
276
- return { tarball: asset.browser_download_url, version: release.tag_name };
277
- }
278
-
279
- // 3. Download and extract
280
- const tarball = await download(resolved.tarball);
281
- await extract(tarball, targetDir);
282
-
283
- // 4. Run post-install hooks
284
- await runHook('postinstall', targetDir);
285
-
286
- // 5. Update local manifest
287
- await updateManifest(name, resolved.version);
288
- ```
289
-
290
- **GitHub Releases approach**: Build artifacts (tarballs, binaries) are attached to GitHub releases. The CLI queries the GitHub API for the latest release, finds the right asset for the platform, downloads and extracts it.
291
-
292
- **npm Registry approach**: The CLI runs `npm pack` or queries the registry API directly, downloads the tarball, and extracts it to a plugin directory.
293
-
294
- **Custom registry approach**: A JSON manifest maps package names to download URLs and metadata. The CLI fetches the manifest, resolves the URL, downloads the artifact.
295
-
296
- ### 9. Building Packages for Dual CJS/ESM Distribution
297
-
298
- Modern packages must support both CommonJS and ES Modules:
299
-
300
- #### package.json Exports Map
301
-
302
- ```json
303
- {
304
- "name": "my-lib",
305
- "type": "module",
306
- "exports": {
307
- ".": {
308
- "import": "./dist/index.mjs",
309
- "require": "./dist/index.cjs",
310
- "types": "./dist/index.d.ts"
311
- },
312
- "./utils": {
313
- "import": "./dist/utils.mjs",
314
- "require": "./dist/utils.cjs",
315
- "types": "./dist/utils.d.ts"
316
- }
317
- }
318
- }
319
- ```
320
-
321
- #### Build Tools
322
-
323
- | Tool | Status | Approach |
324
- |------|--------|----------|
325
- | **unbuild** | Active | Auto-infers from package.json, rollup-based |
326
- | **pkgroll** | Active | Reads exports field, zero-config rollup |
327
- | **tsup** | Migrating to tsdown | esbuild-based, fast |
328
- | **Rollup** | Active | Low-level, maximum control |
329
-
330
- #### Type Checking
331
-
332
- Use `@arethetypeswrong/cli` to verify packages resolve correctly across all module resolution modes (node10, node16, bundler). This catches common issues like types not matching the actual module format.
333
-
334
- ### 10. Workspace Architecture Patterns
335
-
336
- #### Cargo Workspaces (Rust)
337
-
338
- ```toml
339
- # Cargo.toml (root)
340
- [workspace]
341
- members = ["crates/*"]
342
-
343
- [workspace.dependencies]
344
- serde = "1.0"
345
-
346
- # crates/my-lib/Cargo.toml
347
- [dependencies]
348
- serde.workspace = true # Inherits version from root
349
- ```
350
-
351
- Shared `Cargo.lock`, unified build output, configurable default members.
352
-
353
- #### Go Modules
354
-
355
- Go takes a different approach -- each module is independently versioned with its own `go.mod`. Multi-module repos are possible but less common. The `golang.org/x/*` packages demonstrate the pattern of a standard library extended by independent modules.
356
-
357
- #### Python Extras
358
-
359
- Python uses `extras_require` for optional dependency groups:
360
-
361
- ```python
362
- # setup.py
363
- setup(
364
- name="my-lib",
365
- install_requires=["core-dep"],
366
- extras_require={
367
- "full": ["optional-dep-1", "optional-dep-2"],
368
- "dev": ["pytest", "mypy"],
369
- }
370
- )
371
- ```
372
-
373
- Users install with: `pip install my-lib[full]`
374
-
375
- #### Nix
376
-
377
- Nixpkgs is a single repository of 120,000+ package definitions. Users declaratively specify which packages they want, and Nix resolves and builds only those. The collection is monolithic in source but selective in installation.
378
-
379
- ## Code Examples
380
-
381
- ### Meta-Package with Re-Exports
382
-
383
- ```javascript
384
- // packages/my-framework/package.json
385
- {
386
- "name": "my-framework",
387
- "version": "2.0.0",
388
- "dependencies": {
389
- "@my-framework/core": "2.0.0",
390
- "@my-framework/router": "2.0.0",
391
- "@my-framework/store": "2.0.0"
392
- },
393
- "exports": {
394
- ".": "./src/index.js",
395
- "./core": { "import": "@my-framework/core" },
396
- "./router": { "import": "@my-framework/router" },
397
- "./store": { "import": "@my-framework/store" }
398
- }
399
- }
400
-
401
- // packages/my-framework/src/index.js
402
- export * from '@my-framework/core';
403
- export * from '@my-framework/router';
404
- export * from '@my-framework/store';
405
- ```
406
-
407
- ### Monorepo with pnpm Workspaces + Changesets
408
-
409
- ```yaml
410
- # pnpm-workspace.yaml
411
- packages:
412
- - 'packages/*'
413
- - 'plugins/*'
414
- ```
415
-
416
- ```json
417
- // packages/core/package.json
418
- {
419
- "name": "@my-lib/core",
420
- "version": "1.3.0",
421
- "dependencies": {
422
- "@my-lib/utils": "workspace:^"
423
- }
424
- }
425
- ```
426
-
427
- ```bash
428
- # Development workflow
429
- pnpm install # Links workspace packages
430
- pnpm --filter @my-lib/core build
431
-
432
- # Release workflow
433
- npx changeset # Create changeset describing changes
434
- npx changeset version # Bump versions based on changesets
435
- npx changeset publish # Publish all changed packages to npm
436
- ```
437
-
438
- ### Custom CLI Installer (GitHub Releases)
439
-
440
- ```javascript
441
- #!/usr/bin/env node
442
- import { createWriteStream } from 'node:fs';
443
- import { pipeline } from 'node:stream/promises';
444
- import { extract } from 'tar';
445
-
446
- async function install(packageName) {
447
- // 1. Query GitHub API for latest release
448
- const response = await fetch(
449
- `https://api.github.com/repos/my-org/${packageName}/releases/latest`,
450
- { headers: { 'Accept': 'application/vnd.github.v3+json' } }
451
- );
452
- const release = await response.json();
453
-
454
- // 2. Find platform-appropriate asset
455
- const platform = `${process.platform}-${process.arch}`;
456
- const asset = release.assets.find(a => a.name.includes(platform));
457
- if (!asset) throw new Error(`No binary for ${platform}`);
458
-
459
- // 3. Download tarball
460
- const download = await fetch(asset.browser_download_url);
461
-
462
- // 4. Extract to plugins directory
463
- await pipeline(
464
- download.body,
465
- extract({ cwd: `./plugins/${packageName}` })
466
- );
467
-
468
- // 5. Record in manifest
469
- const manifest = JSON.parse(await readFile('./plugins/manifest.json', 'utf8'));
470
- manifest[packageName] = { version: release.tag_name, installed: new Date().toISOString() };
471
- await writeFile('./plugins/manifest.json', JSON.stringify(manifest, null, 2));
472
-
473
- console.log(`Installed ${packageName}@${release.tag_name}`);
474
- }
475
- ```
476
-
477
- ### Plugin Architecture with Peer Dependencies
478
-
479
- ```json
480
- // Plugin package.json
481
- {
482
- "name": "@my-tool/plugin-typescript",
483
- "version": "1.0.0",
484
- "peerDependencies": {
485
- "@my-tool/core": "^2.0.0"
486
- },
487
- "peerDependenciesMeta": {
488
- "@my-tool/core": {
489
- "optional": false
490
- }
491
- }
492
- }
493
- ```
494
-
495
- ```javascript
496
- // Plugin implementation
497
- export default function typescriptPlugin(options = {}) {
498
- return {
499
- name: 'typescript',
500
- setup(api) {
501
- api.onTransform({ filter: /\.tsx?$/ }, async (args) => {
502
- const result = await transpile(args.contents, options);
503
- return { contents: result.code };
504
- });
505
- }
506
- };
507
- }
508
- ```
509
-
510
- ## Common Pitfalls
511
-
512
- | Pitfall | Why It Happens | How to Avoid |
513
- |---------|---------------|--------------|
514
- | Version mismatch between sibling packages | Independent versioning with implicit compatibility assumptions | Use peer dependencies, fixed versioning, or workspace protocol |
515
- | Publishing with `workspace:*` references | Forgetting to let tooling resolve workspace refs | Use Changesets or Lerna publish which handle resolution |
516
- | Duplicate dependencies in bundle | Multiple packages pull in different versions of shared dep | Use workspace hoisting, peerDependencies, or deduplication |
517
- | Per-method packages becoming unmaintainable | N methods = N packages to version/publish/test | Prefer ES modules + tree-shaking over per-function packages |
518
- | CJS/ESM dual package hazard | Same package loaded as both CJS and ESM creates two instances | Use exports map correctly, test with arethetypeswrong |
519
- | Circular dependencies between packages | Organic growth without dependency graph discipline | Enforce layered architecture, use tools like Nx to detect cycles |
520
- | Breaking changes in plugin API | Plugins depend on internal APIs that change | Use semantic versioning on plugin API, separate public API types |
521
- | Stale lockfile after workspace changes | Adding/removing workspace packages without updating lock | Run `pnpm install` / `npm install` after structural changes |
522
-
523
- ## Best Practices
524
-
525
- Synthesized from 40 sources:
526
-
527
- 1. **Start monolithic, split when needed**: Ship a single package first. Only modularize when bundle size, team boundaries, or independent release cycles demand it.
528
-
529
- 2. **Use pnpm workspaces for new monorepos**: Content-addressable storage prevents phantom dependencies. Strict mode catches accidental cross-package imports.
530
-
531
- 3. **Adopt Changesets for version management**: Intent-based changelogs (written at PR time) scale better than automated commit message parsing for multi-package repos.
532
-
533
- 4. **Provide a meta-package for convenience**: Even after modularizing, always offer a single-install option that pulls in common packages together.
534
-
535
- 5. **Use the exports map**: Define explicit entry points in package.json#exports. This enables subpath imports and prevents deep imports into package internals.
536
-
537
- 6. **Declare plugin hosts as peer dependencies**: Plugins should `peerDependency` their host package to avoid version conflicts and duplicate instances.
538
-
539
- 7. **Test dual CJS/ESM with arethetypeswrong**: Verify your package resolves correctly across all Node.js module resolution modes before publishing.
540
-
541
- 8. **Use workspace protocol for internal deps**: `workspace:^` during development, resolved to real versions at publish time.
542
-
543
- 9. **Prefer tree-shaking over per-function packages**: Modern bundlers handle dead code elimination well. ES module exports are more maintainable than hundreds of micro-packages.
544
-
545
- 10. **Automate releases in CI**: Use semantic-release or Changesets GitHub Action to remove human error from the publish process.
546
-
547
- 11. **Cache aggressively in installer CLIs**: degit/tiged cache tarballs locally. Custom CLIs should cache downloaded artifacts with version-based invalidation.
548
-
549
- 12. **Pin exact versions in lockfiles, use ranges in package.json**: Lockfiles ensure reproducibility. Semver ranges in package.json allow consumers flexibility.
550
-
551
- ## Further Reading
552
-
553
- | Resource | Type | Why Recommended |
554
- |----------|------|-----------------|
555
- | [AWS SDK v3 Migration Guide](https://github.com/aws/aws-sdk-js-v3/blob/main/UPGRADING.md) | Migration Guide | Definitive case study of monolith-to-modular migration |
556
- | [Changesets](https://github.com/changesets/changesets) | Tool | Best-in-class monorepo version management |
557
- | [Lerna](https://lerna.js.org) | Tool | Established monorepo publishing (now maintained by Nx) |
558
- | [Turborepo](https://turbo.build/repo) | Tool | Fast monorepo build orchestration |
559
- | [Nx](https://nx.dev) | Tool | Full-featured monorepo platform with caching |
560
- | [Rush](https://rushstack.io) | Tool | Enterprise-scale monorepo management |
561
- | [pnpm Workspaces](https://pnpm.io/workspaces) | Docs | Recommended workspace manager |
562
- | [degit](https://github.com/Rich-Harris/degit) / [tiged](https://github.com/tiged/tiged) | Tool | Template cloning without git history |
563
- | [pkgroll](https://github.com/privatenumber/pkgroll) | Tool | Zero-config package building from exports map |
564
- | [unbuild](https://github.com/unjs/unbuild) | Tool | Auto-inferred library builds |
565
- | [arethetypeswrong](https://arethetypeswrong.github.io) | Tool | Verify CJS/ESM type correctness |
566
- | [semantic-release](https://github.com/semantic-release/semantic-release) | Tool | Automated versioning from commits |
567
- | [np](https://github.com/sindresorhus/np) | Tool | Interactive npm publish workflow |
568
- | [GoReleaser](https://goreleaser.com) | Tool | Binary distribution via GitHub Releases |
569
- | [Effect](https://github.com/Effect-TS/effect) | Example | Modern scoped-package monorepo architecture |
570
- | [Astro Integrations](https://github.com/withastro/astro) | Example | Core + official integrations pattern |
571
- | [Babel Plugins](https://github.com/babel/babel) | Example | Core + plugin + preset architecture |
572
-
573
- ---
574
-
575
- *Generated by /learn from 40 sources.*
576
- *See `resources/all-in-one-plus-modular-packages-sources.json` for full source metadata.*