The AI SDK core has no Next.js dependency. On Express you pipe the stream to the response; in scripts you iterate the stream directly.

Express:

import { convertToModelMessages, streamText } from 'ai';

app.post('/api/chat', async (req, res) => {
  const { messages } = req.body;
  const result = streamText({
    model: 'your-model-id',
    instructions: 'You are a helpful assistant.',
    messages: await convertToModelMessages(messages),
    abortSignal: req.signal,
  });
  result.pipeUIMessageStreamToResponse(res);
});

Plain Node script:

import { streamText } from 'ai';

const { textStream } = streamText({ model: 'your-model-id', prompt: 'Write a haiku.' });
for await (const textPart of textStream) {
  process.stdout.write(textPart);
}

Checklist:
1. Install only ai (plus zod for tools and dotenv for keys): pnpm add ai zod dotenv, dev deps tsx and typescript to run it. No Next.js, no react package needed.
2. Keys come from environment variables (OPENAI_API_KEY etc.). Load them with dotenv in scripts; on servers use the platform env.
3. For a chat UI talking to Express, the frontend still uses useChat with DefaultChatTransport({ api: 'https://your-host/api/chat' }). The wire protocol is framework-agnostic.
4. Wrap streaming calls in try/catch. For simple text streams errors throw as regular errors; for UI message streams, handle 'error' parts on result.stream too.
5. Node 22+ is the documented baseline. Older Node versions lack the fetch/Response globals the SDK builds on.
6. If you need the full typed part stream (tool calls, reasoning, sources), iterate result.stream instead of textStream and switch on part.type.