Chapter 0 · Foundations
Setup
7 min read · 2 of 12
You’re going to want everything in this chapter working before you turn the page to Chapter 1. This is short, so just do it.
Quick setup
# 1. Install Node 24 LTS (via nvm or your installer) - check https://nodejs.org/en for the details
nvm install --lts && nvm use --lts
# 2. Get a Gemini API key
# https://aistudio.google.com → Get API Key → New project
# 3. Init a project
mkdir my-ai-book && cd my-ai-book
npm init -y
npm pkg set type=module
npm install @google/genai
npm install --save-dev typescript @types/node
# 4. Save the key to a local .env file (and gitignore it)
echo 'GEMINI_API_KEY=paste-your-key-here' > .env
echo '.env' >> .gitignore
# 5. Verify - create hello.ts
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({});
const r = await ai.models.generateContent({
model: "gemini-3.5-flash",
contents: "Say hello in five words.",
});
console.log(r.text);
node --env-file=.env --experimental-strip-types hello.ts
If that prints a short greeting, you’re done. Skip to Chapter 1.
If it didn’t, the rest of this chapter walks you through the same steps and tells you what usually goes wrong.
Node version
Use Node 24 LTS or newer. Node 24 went LTS in October 2025 and is the active LTS line through April 2028. Node 22 (Jod) is in maintenance and works fine if you’re already on it. Node 20 (Iron) reached end of LTS in April 2026; move off it.
Check what you have:
node --version
If that prints v24.x.x, you’re set. If it prints v22.x.x, also fine, but you’ll need an extra flag (covered below). Older than 22, upgrade.
The cleanest way to manage Node versions is nvm on macOS/Linux or fnm on Windows. Both let you switch versions per-project. If you’re using a system installer or Volta or asdf, those also work.
# macOS / Linux via nvm
nvm install --lts
nvm use --lts
# Windows via fnm
fnm install --lts
fnm use lts-latest
Why this matters. The book uses two Node features. --env-file was added in Node 20.6.0. Native TypeScript stripping landed behind --experimental-strip-types in Node 22.6.0 and became the default (no flag needed) in Node 23.6.0, backported to the 22.18.0 LTS and on by default in Node 24. The flag the book passes is a no-op when stripping is already the default, but I include it explicitly so the intent is documented in every command. If you’re on Node older than 22.6, the commands in this book will throw confusing errors, so upgrade.
No tsx. No dotenv. No export.
A short detour, because this is where the book diverges from most TypeScript tutorials you’ve seen.
The book runs TypeScript with Node itself, using the built-in --experimental-strip-types flag. No tsx, no ts-node, no swc-node. Node 24 strips types by default; the flag still works as an explicit toggle and we’ll use it in the commands so the intent is documented in the source. Why? The honest answer: it is just simpler to teach it this way.
The book loads environment variables with Node itself, using the built-in --env-file flag. No dotenv package. No import "dotenv/config" lines at the top of every file. No export GEMINI_API_KEY=... in your shell rc.
Fewer dependencies you have to audit and update. Every package you don’t install is a package that can’t break, get a CVE, or introduce a typo-squatting risk.
The combined run command, which you’ll see throughout the book:
node --env-file=.env --experimental-strip-types script.ts
That’s the whole runtime story.
Package manager
Use npm. It comes with Node, it works, and it’s one less tool to debug.
If you prefer pnpm, bun, or yarn, they all work. Commands are equivalent (pnpm install instead of npm install, etc.). I won’t show four ways to do the same thing in the prose.
The one exception worth knowing: bun includes its own TypeScript runner. If you’re on bun, swap node --env-file=.env --experimental-strip-types <file>.ts for bun --env-file=.env <file>.ts (bun runs TypeScript natively without a flag).
Project structure
Each chapter’s code lives in its own folder under code/:
my-ai-book/
├── code/
│ ├── chapter-00/
│ ├── chapter-01/
│ ├── chapter-02/
│ └── ...
Each chapter folder is its own npm project: its own package.json, its own node_modules, its own dependencies. Different chapters can use different versions of different packages without conflict, and you can cd into one folder and run its code without dragging the whole book’s deps along.
TypeScript dev dependencies
You don’t need a runtime TS package. The Node strip-types flag handles execution. You do want type-checking and editor support, so install:
npm install --save-dev typescript @types/node
These give your editor the type-checking experience you’re used to. They’re not used at runtime.
If you want a tsconfig.json for stricter editor checks, generate a basic one:
npx tsc --init --target ESNext --module NodeNext --moduleResolution NodeNext --strict
The book’s code samples don’t require a tsconfig.json. If you don’t add one, your editor will use sensible defaults.
API key from Google AI Studio
Go to https://aistudio.google.com.
Sign in with a Google account. Click Get API Key in the left nav. Click Create API key. Pick a project (or create a new one).
Copy the key.
You may need to create a billing account under your Google Cloud Console, but given that each setup for this may be different I will leave that to you, the reader, to setup.
Keep the key out of git. Don’t paste it into source code. Don’t commit it. If you accidentally commit it, regenerate it from AI Studio and rotate before you forget.
The .env file
In each chapter folder you actively work in, create a .env:
echo 'GEMINI_API_KEY=AIzaSy...' > .env
echo '.env' >> .gitignore
That’s it. No package to install. No import to add. When you run a script with node --env-file=.env, Node reads the file and adds every KEY=value line to process.env before your script starts.
In your TypeScript:
const key = process.env.GEMINI_API_KEY;
Just works. No setup, no library.
The .gitignore line is non-negotiable. If you skip it, your key ends up in git the first time you commit, and probably on GitHub the first time you push. Every model provider has a story about a developer who leaked a key this way and got billed for crypto-mining within an hour. Don’t be one of them.
If you keep multiple chapter folders open and want one global .env, you can put it at the project root and pass --env-file=../../.env to Node. It works the same.
Editor
Use whatever you already use. The book is editor-agnostic. Two notes:
VS Code. The TypeScript and JavaScript Language Features extension is built in; you already have it. Add Error Lens for inline error display (very nice with TypeScript). For AI-assisted coding, GitHub Copilot or Continue.dev both work.
Cursor. VS Code with built-in AI. Fine choice, no book changes required.
Other. Zed, JetBrains, Neovim, Vim, Sublime, Emacs all work. Nothing in the book asks you to do something editor-specific.
Next up in Chapter 1: An LLM is not a function. Now that the plumbing works, we look at what’s actually on the other end of that API call.