Seven @forge packages ship no changelog, so I diffed their majors

93317 has been open for a year. michael5 asked what breaks when @forge/kvs goes 1.x to 2.0.0, DavidPezet1 found that some packages hide a CHANGELOG.md inside the tarball, and @scottohara re-raised it last month because @forge/kvs still has none. I measured the whole scope, then diffed the majors, because the useful question is not how many files are missing. It is what they would have said.

The census

47 packages in the @forge scope, latest published version of each, downloaded and listed. 40 ship a CHANGELOG.md. In the other seven the only documentation files are README.md and LICENSE.txt:

@forge/storage 2.0.3
@forge/kvs 2.0.4
@forge/sql 4.0.4
@forge/cache 2.0.4
@forge/object-store 2.0.4
@forge/teamwork-graph 5.0.4
@forge/runtime-bootstrap 1.11.4 (LICENSE.txt only, no README)

Six of the seven are the storage and data-plane SDKs. I checked every stable version of those six, going back through their history. @forge/kvs, @forge/sql, @forge/cache, @forge/object-store and @forge/teamwork-graph have shipped 224 stable versions between them and not one carries the file. @forge/storage is the exception and the interesting case: it had a changelog in 13 versions, up to 1.5.0 on 6 April 2023, and lost it at 1.5.1 twenty days later. This is a file that was removed, and it has been missing from the data packages ever since.

Enumerating the scope takes pagination, by the way. text=scope:forge returns nothing at all, and a plain @forge search gives you 34 of the 47 unless you page with &from=250.

Reading the ones that exist

You do not need npm pack. unpkg serves any published file of any published version:

curl https://unpkg.com/@forge/api@8.0.4/CHANGELOG.md

That is where the 8.0.0 entry lives: Remove "storage" module from "@forge/api". None of the seven above declare a repository, so npm repo @forge/kvs prints npm error no repository.

For the seven, diff two versions

for v in 1.6.5 2.0.0; do
  npm pack @forge/kvs@$v
  mkdir -p kvs-$v && tar xzf forge-kvs-$v.tgz -C kvs-$v --strip-components=1
done
diff kvs-1.6.5/package.json kvs-2.0.0/package.json
diff -rq kvs-1.6.5/out kvs-2.0.0/out

Extract with -C and --strip-components=1 rather than into package/. I did it the lazy way first and a second tarball merged into the leftovers of the first, which fills the diff with phantom Only in lines.

For @forge/kvs 2.0.0 the package.json is the whole story:

-  "dependencies": { "@forge/api": "^7.2.2" }
+  "dependencies": { "@forge/api": "^8.0.0" },
+  "peerDependencies": { "typescript": ">=5.0.0" },
+  "peerDependenciesMeta": { "typescript": { "optional": true } }

The out/ diff is 14 lines and every one is TypeScript declaration emit: type aliases lose declare, CommonJS function exports move to a hoisted exports.X = X, enums lose the (X = exports.X || (exports.X = {})) wrapper. Normalise that and every .d.ts is byte-identical. I ran the same normalised diff on @forge/sql 4.0.0 and it leaves nothing at all. I ran it on @forge/cache 2.0.0 and the only residue is two lines of data?: any becoming data?: any | undefined, which is the same type.

Two of them did move, and nothing says so

The other two majors from 22 June are not emit noise. @forge/object-store 2.0.0 widened a method and added an exported type:

-createCDNUrl(key: string): Promise<PresignedUrlResponse | undefined>;
+createCDNUrl(key: string, options?: CDNOptions): Promise<PresignedUrlResponse | undefined>;

@forge/teamwork-graph 5.0.0 recased SpaceSubtype, which is a required property of SpaceAttributes:

-export declare type SpaceSubtype = 'space' | 'project' | 'business' | 'software' | 'service_desk' | 'site' | 'drive';
+export type SpaceSubtype = 'SPACE' | 'PROJECT' | 'BUSINESS' | 'SOFTWARE' | 'SERVICE_DESK' | 'SITE' | 'DRIVE';

Those are values you push into the graph. I searched all 1514 entries in the platform changelog for SpaceSubtype, createCDNUrl, CDNOptions and SERVICE_DESK and got nothing, on a search where typescript returns 11.

The peer dependency is optional and that does not save you

peerDependenciesMeta marks TypeScript optional, so I built three trees and installed @forge/kvs@2.0.0 into each. No TypeScript at all: clean, 53 packages. TypeScript 5.9.2: clean. TypeScript 4.9.5:

npm error peerOptional typescript@">=5.0.0" from @forge/kvs@2.0.0
npm error Could not resolve dependency

The install is refused outright. There is no warning to read past. A JavaScript-only Forge app is untouched by the whole wave, and a TypeScript 4 app cannot install any of it without --legacy-peer-deps.

The instruction that does not compile

The removal of storage from @forge/api in 8.0.0 was announced properly, in changelog entry CHANGE-3252, 22 June 2026, “Removal of legacy storage module from @forge/api package”, warning that apps still importing it will fail to build or run. It then says what to do.

Update your imports from import { storage } from '@forge/api' to import { storage } from '@forge/kvs'

That does not work, and I nearly repeated it here before checking. @forge/kvs exports no such name, at 2.0.4 or back at 1.0.0:

$ node -e "console.log(Object.keys(require('@forge/kvs')))"
[ 'FilterConditions', 'WhereConditions', 'Filter', 'kvs', 'ForgeKvsError',
  'ForgeKvsAPIError', 'MetadataField', 'Sort', 'isOverrideAndReturnOptions', 'default' ]

It is import { kvs } from '@forge/kvs', and it is not a rename either. Atlassian’s own migration guide has sections headed “Replace startsWith filter with beginsWith” and “Replace sortOrder with Sort”.

The storage reference has not caught up at all. Eight weeks after the removal it still reads:

The legacy storage module from @forge/api is still supported but no longer receives feature updates (as of March 17, 2025).

Hopefully by the end of 2027 this platform is primarily managed by agents.

And the human layer operating through a central world model so there’s org-wide coherence.

Hi @nathanwaters, the changelog gap cuts against that though. An agent upgrading @forge/kvs across a major has nothing to read but the diff: no CHANGELOG.md in the package, no migration note, and CHANGE-3252’s own suggested import does not compile.

I would say coherence needs something machine readable to be coherent about, and right now the tarball is the only source that is reliably current.

Hi @Mihai_leanzero ,

Thanks for raising these issues with us. There was a bug in our package config which meant we weren’t publishing changelogs as part of our package. This has been fixed and will start seeing the changelogs in next package release of these libraries and will have. This will include full changelog history and not just a changelog starting from the current version.

In regards to our storage documentation, it was something we should’ve caught in the changelog and we’re in the process of updating our documentation and removing references to the old storage api.

Thanks for raising this.

Hi @LukeD, thanks, and five of the seven already have it. The kvs, sql, cache, object-store and teamwork-graph packages each published a next build at 07:24 UTC today carrying CHANGELOG.md, which I pulled and read this morning. The kvs one goes back to its first ever publish, 0.0.2-next.0, so I think the full-history part is genuinely done rather than truncated.

The two outside that wave are @forge/storage and @forge/runtime-bootstrap. Their latest and next are both still 2025 builds. Are those deliberately out of scope, or waiting on a release?

Those are deliberately out of scope as they’re no longer supported packages.

Hi @LukeD, thanks, that answers it.

Unsupported doesn’t show up on npm though. Neither package carries a deprecated field on any published version, so nothing warns you:

$ npm install @forge/storage
added 1 package, and audited 2 packages in 443ms

found 0 vulnerabilities

I’d say @forge/storage is the one that matters: @forge/api depended on it right up to 7.x and only dropped it in 8, so it is sitting in the tree of anyone who has not upgraded, without them asking for it. An npm deprecate on it would put your answer where a build can see it.