Summary
@ainative/ai-kit@0.2.1 has no browser-safe entry point. Its single dist/index.mjs (used by both import and ./react in package.json's exports map) bundles server-only code into the same bundle as its client-facing React hooks, so importing anything from the package into a Client Component breaks the build in any bundler that respects "use client" boundaries (confirmed with Next.js 16 / Turbopack).
Repro
npm install @ainative/ai-kit
"use client";
import { useAIStream } from "@ainative/ai-kit";
export default function Chat() {
const { messages, send, isStreaming } = useAIStream({ endpoint: "/api/chat" });
// ...
}
Actual result
Build fails with three Module not found errors, all originating from @ainative/ai-kit-core/dist/index.mjs (which @ainative/ai-kit's index.mjs imports from):
./node_modules/@ainative/ai-kit-core/dist/index.mjs:5:1
Error: Module not found: Can't resolve 'fs'
3 | import { createHash, randomBytes, createCipheriv, createDecipheriv, randomUUID } from 'crypto';
4 | import Redis from 'ioredis';
> 5 | import { promises, createReadStream, createWriteStream } from 'fs';
6 | import * as path from 'path';
7 | import { createGzip } from 'zlib';
./node_modules/@ainative/ai-kit-core/dist/index.mjs:4:1
Error: Module not found: Can't resolve 'ioredis'
./node_modules/@ainative/ai-kit-core/dist/index.mjs:8:1
Error: Module not found: Can't resolve 'stream/promises'
Import trace confirms it's reached purely through the client hook import:
Client Component Browser:
./node_modules/@ainative/ai-kit-core/dist/index.mjs [Client Component Browser]
./node_modules/@ainative/ai-kit/dist/index.mjs [Client Component Browser]
./src/components/AssistantChat.tsx [Client Component Browser]
Root cause (inspected directly)
@ainative/ai-kit-core/dist/index.mjs is a single bundle containing both:
- Browser-safe primitives (
AIStream, useAIStream, useConversation, StreamingMessage, etc.)
- Node-only persistence code (
ZeroDBSessionStore/ZeroDBStorage, which pulls in ioredis, fs, stream/promises)
There's a dist/browser.mjs and dist/server.mjs in @ainative/ai-kit-core that appear to already split these concerns correctly at that layer — but @ainative/ai-kit's own package.json exports map only points at one undifferentiated dist/index.mjs, with no browser condition, so consumers can't reach the already-built browser-safe split.
"exports": {
".": { "types": "./dist/index.d.ts", "import": "./dist/index.mjs", "require": "./dist/index.js" },
"./react": { "types": "./dist/index.d.ts", "import": "./dist/index.mjs", "require": "./dist/index.js" }
}
Secondary issue: missing .d.ts
package.json declares "types": "./dist/index.d.ts", but the published tarball does not contain dist/index.d.ts — only index.js, index.js.map, index.mjs, index.mjs.map. Any TypeScript consumer gets TS7016: Could not find a declaration file for module '@ainative/ai-kit'. Worked around locally with a hand-written ambient module declaration matching the real exports inspected from the compiled JS, but this should ship for real.
Suggested fix
Add a browser export condition (and/or split @ainative/ai-kit itself into a client-safe entry that only re-exports the browser-safe subset of @ainative/ai-kit-core, mirroring the browser.mjs/server.mjs split that already exists one level down), and include the built .d.ts in the published package.
Environment
@ainative/ai-kit@0.2.1, @ainative/ai-kit-core@0.2.0
- Next.js 16.3.5, Turbopack
- Node 22.19.0
Summary
@ainative/ai-kit@0.2.1has no browser-safe entry point. Its singledist/index.mjs(used by bothimportand./reactinpackage.json'sexportsmap) bundles server-only code into the same bundle as its client-facing React hooks, so importing anything from the package into a Client Component breaks the build in any bundler that respects"use client"boundaries (confirmed with Next.js 16 / Turbopack).Repro
Actual result
Build fails with three
Module not founderrors, all originating from@ainative/ai-kit-core/dist/index.mjs(which@ainative/ai-kit'sindex.mjsimports from):Import trace confirms it's reached purely through the client hook import:
Root cause (inspected directly)
@ainative/ai-kit-core/dist/index.mjsis a single bundle containing both:AIStream,useAIStream,useConversation,StreamingMessage, etc.)ZeroDBSessionStore/ZeroDBStorage, which pulls inioredis,fs,stream/promises)There's a
dist/browser.mjsanddist/server.mjsin@ainative/ai-kit-corethat appear to already split these concerns correctly at that layer — but@ainative/ai-kit's ownpackage.jsonexportsmap only points at one undifferentiateddist/index.mjs, with nobrowsercondition, so consumers can't reach the already-built browser-safe split.Secondary issue: missing
.d.tspackage.jsondeclares"types": "./dist/index.d.ts", but the published tarball does not containdist/index.d.ts— onlyindex.js,index.js.map,index.mjs,index.mjs.map. Any TypeScript consumer getsTS7016: Could not find a declaration file for module '@ainative/ai-kit'. Worked around locally with a hand-written ambient module declaration matching the real exports inspected from the compiled JS, but this should ship for real.Suggested fix
Add a
browserexport condition (and/or split@ainative/ai-kititself into a client-safe entry that only re-exports the browser-safe subset of@ainative/ai-kit-core, mirroring thebrowser.mjs/server.mjssplit that already exists one level down), and include the built.d.tsin the published package.Environment
@ainative/ai-kit@0.2.1,@ainative/ai-kit-core@0.2.0