Skip to content
AI Full-Stack Wiki

AI Engineering Resources: Official Docs and References Worth Bookmarking

A curated list of primary sources for AI full-stack engineers: model and SDK docs, MCP, web stack, databases, retrieval, observability, and security, plus a link checker.

Difficulty: Beginner7 min readUpdated
On this page· Where each resource fits

Why this matters

When something changes, the official documentation is right and blog posts are not yet. A short list of primary sources, organized by the part of the stack they cover, saves time every week and keeps you from learning outdated patterns. Everything below is a primary source: documentation, specifications, or the repositories of the tools themselves.

Where each resource fits#

Full-stack architecture of an AI applicationA React UI talks to a Node.js API layer that handles auth, caching, Postgres with pgvector, a job queue with workers, observability, and calls to third-party model APIs whose tokens stream back to the browser.usesHTTPS requestSSE streamverify sessioncacheenqueue jobjobstracesTHIRD-PARTY APISUserReact UINext.js clientAPI layerRoute handlers / ExpressAuthSessions, permissionsRedisCache, rate limitsPostgrespgvector embeddingsJob queueBackground workWorkersIndexing, long tasksObservabilityTraces, cost, evalsModel APIsLLM + embeddings

Hover or tap a component to see what it does.

Full-stack architecture of an AI application: a React frontend, a Node.js API layer that owns every model call, Postgres with pgvector for data and embeddings, Redis, a job queue with workers, observability, and third-party model APIs.
Show text description

The diagram shows a production AI web application as boxes inside two trust zones: your own infrastructure, and third-party model APIs. Solid arrows are requests, dashed arrows are asynchronous jobs and telemetry, and arrows with moving dots are streamed responses.

  • User: The person using your product in a browser or mobile app.
  • React UI: Renders the chat or feature UI, sends requests to your API, and renders streamed tokens as they arrive. Never holds model API keys.
  • API layer: The only place that talks to model providers. Validates input, checks auth and rate limits, assembles context, calls the model, and streams the answer back over Server-Sent Events.
  • Auth: Identifies the user and decides what data and tools they may access. Every model call and tool call inherits these permissions.
  • Redis: Fast key-value store for per-user rate limits, response caching, and short-lived session state.
  • Postgres: The system of record: users, conversations, and documents. The pgvector extension stores embeddings so the same database answers similarity searches for RAG.
  • Job queue: Holds slow work (document indexing, long agent runs, batch jobs) so API requests return quickly. Jobs survive restarts and can be retried.
  • Workers: Node.js processes that pull jobs from the queue: chunk documents, request embeddings, write vectors to Postgres, and run long tasks with retries.
  • Observability: Collects a trace for every request and job, with prompts, token counts, latency, and cost, so you can debug bad answers and run evals on real traffic.
  • Model APIs: Hosted models reached over HTTPS: an LLM for generation and tool use, and an embedding model for vector search. Stateless: every request must carry its full context.

Chat request. The UI posts the message to your API, which verifies the session, checks the rate limit in Redis, retrieves context from Postgres, calls the model, and streams tokens back to the browser over SSE.

Document indexing. An upload is acknowledged immediately and queued. A worker chunks the document, requests embeddings from the model API, and writes the vectors to pgvector.

Observability. The API and workers emit a trace for every request and job, with token counts, latency, and cost. Traces feed dashboards, alerts, and evals on real traffic.

Models and APIs#

Model Context Protocol#

The web stack#

Data and retrieval#

Production#

Keeping this list healthy#

Links rot. This script extracts external links from a Markdown or MDX file and checks each one, so a scheduled CI job can tell you when a resource moves:

lib/links.ts
/** External http(s) links from Markdown inline links, without duplicates, in order of appearance. */
export function extractLinks(markdown: string): string[] {
  const prose = markdown.replace(/^`{3}[\s\S]*?^`{3}/gm, ""); // links inside code examples are not resources
  const urls = [...prose.matchAll(/\[[^\]]*\]\((https?:\/\/[^)\s]+)\)/g)].map((m) => m[1]!);
  return [...new Set(urls)];
}
 
export interface LinkResult {
  url: string;
  status: number | "error";
  ok: boolean;
}
 
export async function checkLink(url: string, timeoutMs = 10_000): Promise<LinkResult> {
  const attempt = (method: "HEAD" | "GET") =>
    fetch(url, { method, redirect: "follow", signal: AbortSignal.timeout(timeoutMs), headers: { "user-agent": "link-checker" } });
  try {
    let res = await attempt("HEAD");
    if (res.status === 405 || res.status === 403) res = await attempt("GET"); // some servers reject HEAD
    return { url, status: res.status, ok: res.ok };
  } catch {
    return { url, status: "error", ok: false };
  }
}
check-links.ts
import { readFileSync } from "node:fs";
import { checkLink, extractLinks } from "./lib/links.ts";
 
const file = process.argv[2] ?? "content/reference/resources.mdx";
const links = extractLinks(readFileSync(file, "utf8"));
const results = await Promise.all(links.map((url) => checkLink(url)));
 
for (const r of results) console.log(`${r.ok ? "ok " : "BAD"} ${r.status} ${r.url}`);
const broken = results.filter((r) => !r.ok);
console.log(`\n${links.length - broken.length}/${links.length} links ok`);
if (broken.length) process.exitCode = 1;
links.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { extractLinks } from "./lib/links.ts";
 
test("extracts unique external links in order", () => {
  const md = "See [a](https://a.example/x), [b](/internal), [a again](https://a.example/x) and [c](http://c.example).";
  assert.deepEqual(extractLinks(md), ["https://a.example/x", "http://c.example"]);
});
 
test("ignores links inside fenced code blocks", () => {
  const md = ["[docs](https://docs.example)", "", "~~~ts", "// [x](https://ignored.example)", "~~~"].join("\n").replaceAll("~~~", "`".repeat(3));
  assert.deepEqual(extractLinks(md), ["https://docs.example"]);
});

Common mistakes#

  • Learning from outdated tutorials. Check the date and the version against the official docs.
  • Bookmarking everything. A short list you actually read beats a long one you do not.
  • Copying examples without checking the SDK version. APIs change; compare with the release notes.

Try it

Build your own list

  1. Add the three sources most relevant to your current project to your own notes, with one line on what you use each for.
  2. Run check-links.ts on this page's source, or on your own notes.
  3. Subscribe to release notifications for the two SDKs you use most.

Check your understanding

Which source should win when a blog post and the official docs disagree?
Why check links automatically?
Why does checkLink retry with GET?

Key takeaways

  • Prefer primary sources: documentation, specifications, and official repositories.
  • Organize resources by the part of the stack they serve.
  • Keep the list short and check links automatically.

Next steps#

Finished this article? Track it to see your progress on the roadmap.