ArkEnv is a monorepo containing a core engine, a CLI codegen tool, multiple framework plugins, and build utilities. Choosing a single versioning strategy for all packages leads to unnecessary releases and coupling.
For example:
- A bug fix in
@arkenv/nextjsshould not force a new version ofarkenv. - A breaking change in
arkenvshould be reflected immediately in@arkenv/clito prevent schema/codegen version mismatches.
We will adopt a hybrid versioning model that combines fixed (locked) versioning for the core inner circle with independent versioning for the outer ring of plugins and utilities.
The following packages are always kept in version lockstep:
arkenv(core engine)@arkenv/cli(codegen tool)
Rationale: @arkenv/cli generates code based on arkenv's schema internals. A version mismatch between the CLI and the core engine can produce incompatible or broken generated files. Keeping them fixed eliminates this class of errors.
The following packages float independently:
- Framework plugins:
@arkenv/nextjs,@arkenv/nuxt,@arkenv/vite-plugin,@arkenv/bun-plugin - Build utilities:
@arkenv/build,@arkenv/fumadocs-ui
Rationale: These packages integrate with external frameworks and tools that evolve on their own schedules. A local integration fix (e.g., adapting to a new Next.js API) should not trigger a core engine release. Independent versioning allows us to ship plugin-specific fixes without cascading version bumps to the entire ecosystem.
All framework plugins declare arkenv as a strict peer dependency:
- This enforces compatibility at the package manager level.
- Users are warned (or blocked) if they install an incompatible plugin/core combination.
- It prevents silent version skew that could break structural typing at runtime.
Because this is a monorepo, plugins reference the local arkenv package during development. We use two different workspace protocols depending on the dependency field:
devDependencies: "arkenv": "workspace:*"
- During local development, this links directly to the workspace package (the folder in
packages/arkenv), regardless of its current version. - When published to npm, pnpm rewrites
workspace:*to the exact current version (e.g.,"1.0.0-alpha.1"). - This is correct for
devDependenciesbecause they are not installed by end users.
peerDependencies: "arkenv": "workspace:^"
- During local development, this also links to the workspace package.
- When published to npm, pnpm rewrites
workspace:^to a caret range (e.g.,"^1.0.0-alpha.1"). - This is mandatory for
peerDependencies. Usingworkspace:*here would publish an exact pin, meaning every patch release ofarkenvwould trigger an unmet peer dependency warning for all users until they manually update every plugin. The caret range allows users to upgradearkenvwithin the major version without friction.
dependencies (Highly Coupled Internals): "arkenv": "workspace:~"
- For internal packages that rely on undocumented or deep-level APIs of
arkenv(e.g., a future@arkenv/parseror codegen utility that reaches into internal schema shapes),workspace:~is the appropriate protocol. - When published, pnpm rewrites
workspace:~to a tilde range (e.g.,"~1.0.0-alpha.1"), which allows patch updates but locks the minor version. - This ensures that a minor feature update to
arkenvcannot silently break the coupled internal tool. Ifarkenvbumps its minor version, the dependent package must also be released and bumped. - Not currently used in the ArkEnv monorepo, but reserved for future highly-coupled internal tools.
| Field | Protocol | Local Dev | Published |
|---|---|---|---|
devDependencies |
workspace:* |
Links to workspace | Exact version (1.0.0-alpha.1) |
peerDependencies |
workspace:^ |
Links to workspace | Caret range (^1.0.0-alpha.1) |
dependencies (tight) |
workspace:~ |
Links to workspace | Tilde range (~1.0.0-alpha.1) |
Reference: See pnpm documentation on publishing workspace packages for full details on how
workspace:protocols are rewritten during publish.
- Positive: Core engine stability. Inner-circle releases are deliberate and reflect genuine engine or codegen changes.
- Positive: Plugin agility. Framework integrations can iterate and release quickly without coordinating with core releases.
- Positive: Clear contract. Users understand that
arkenvand@arkenv/climove together, while plugins move at their own pace. - Positive: Peer dependency enforcement catches mismatched installations early.
- Negative: Slightly more complex release management (Changesets handles this via the
fixedandindependentconfiguration mix). - Negative: Plugin authors must ensure peer dependency ranges accurately reflect tested compatibility.