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'toimport { 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
storagemodule from@forge/apiis still supported but no longer receives feature updates (as of March 17, 2025).