perf(core): make winston an optional peer, ~26 fewer packages on install
- Dominant language
- TypeScript
- Stars
- 1.4k
- Forks
- 205
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 92
Description
Follow-up to #626. After that change `npm install @google/adk` installs 172 packages; `winston` is the second-largest block remaining, behind only MikroORM (#784).
Unlike MikroORM, this one also fixes a browser-bundling defect — see "Two problems, one fix" below.
## Impact
A registry-graph attribution of the current tree measures each block by what disappears when it is removed, so transitive deps shared with other dependencies are not double-counted:
| Block | In tree | Exclusive |
|---|---:|---:|
| MikroORM (#784) | 44 | 44 |
| **`winston`** | **28** | **26** |
| OpenTelemetry block | 33 | 17 |
| `@google/genai` + `google-auth-library` | 41 | 0 (irreducible) |
`winston@3.19.0` pulls 27 transitive packages for what ADK uses as leveled console output:
```
@colors/colors, @dabh/diagnostics, @so-ric/colorspace, @types/triple-beam, async,
color, color-convert, color-name, color-string, enabled, fecha, fn.name, inherits,
is-stream, kuler, logform, ms, one-time, readable-stream, safe-buffer,
safe-stable-stringify, stack-trace, string_decoder, text-hex, triple-beam,
util-deprecate, winston-transport
```
## Two problems, one fix
`winston` is also one of the two blockers in #611 (part of #607): `dist/web/utils/logger.js` imports it, it has no browser shim, and it drags `os`, `fs`, `util`, `zlib`, `http` into the web build. A console-based logger is browser-safe by construction, so replacing `winston` closes the install-size gap **and** removes that unresolved import, rather than needing a shim.
## Why this should be cheap
The entire dependency lives behind one small abstraction per workspace:
- `core/src/utils/logger.ts` — the only `winston` import in `core/src`
- `dev/src/utils/logger.ts` — the only one in `dev/src`
Both expose a `Logger` interface (`log`/`debug`/`info`/`warn`/`error`/`setLogLevel`) and a `LogLevel` enum, implemented by a single `SimpleLogger` class using exactly one `winston` feature set: a `Console` transport plus a `printf` format producing
```
LEVEL: [ADK]
```
with `format.colorize()` for the level. Replacing the internals of `SimpleLogger` leaves the public `Logger` interface and `LogLevel` enum untouched, so this is not an API change for consumers.
## Suggested approach
Replace `SimpleLogger`'s internals with a minimal `console`-backed implementation preserving the current output format and level filtering. Colorization can use ANSI codes directly (a handful of constants) or be dropped when not a TTY, which is the behaviour most consumers want in captured logs anyway.
Worth confirming against #84 (customizing/disabling ADK logs) that whatever replaces it keeps the level control that issue settled on.
If a dependency is preferred over hand-rolling, evaluate it on transitive count before adopting — the point of the change is the 26 packages.
## Acceptance criteria
- [ ] No `winston` import anywhere in `core/src` or `dev/src`, and it is gone from both `package.json` files
- [ ] `npm install @google/adk` into an empty directory drops by ~26 packages
- [ ] The `Logger` interface and `LogLevel` enum are unchanged; no consumer-visible API change
- [ ] Log output format and level filtering behaviour are preserved
- [ ] `dist/web/utils/logger.js` no longer imports a Node-only module, removing that half of #611
- [ ] `unit:core` and `unit:dev` green
## Related
- #626 — the change this follows up
- #784 — MikroORM, the larger sibling block
- #611 / #607 — browser bundling; `winston` is one of the two remaining unresolved imports
- #84 — customizing or disabling ADK logs
Contributor guide
Assessment
This issue has not been assessed yet.