Welcome to BYTE
Your interactive guide to understanding code from scratch.
This guide will take you from "What even IS code?" to "I understand how my entire system works."
Every module has three parts:
2. Code Editor — Write and run real code in your browser
3. Quiz — Test what you learned (earn XP!)
21 modules. Your pace. Click any module in the sidebar or start with Module 1 below.
Pro tip: Click the BYTE button (bottom-right) anytime to ask the AI tutor for help.
What IS Code?
Code is text that tells a computer what to do. That's it. Every app, website, and game is just text files with instructions.
When you write console.log("Hello"), you're saying: "Computer, display the word Hello on screen."
The computer reads your instructions top to bottom, one line at a time, like reading a recipe step by step.
Why JavaScript?
JavaScript runs in every web browser. It's what makes websites interactive. Your apps (Centsable, Adulting Academy, ATLAS) are all built with it. It's the language of the web.
Variables
A variable stores data so you can use it later. Instead of typing the same value everywhere, you store it once and reference it by name.
Three ways to create variables:
let age = 30; — Can be changed later (most common)
const name = "Jamal"; — Cannot be changed (use for things that stay the same)
var old = true; — The old way, avoid this
const by default. Only use let when you know the value will change. Never use var.In Your Apps
In auth.js: const token = jwt.sign({userId}, SECRET) — the token is stored in a variable so it can be returned to the browser.
Data Types
Every value in JavaScript has a type. The type determines what you can do with it.
"Hello" — String (text, always in quotes)
42 — Number (integers and decimals)
true / false — Boolean (yes/no, on/off)
null — Null (intentionally empty)
undefined — Undefined (exists but no value assigned yet)
typeof tells you what type something is. Try it: typeof "hello" returns "string"Operators
+ adds, === asks "are these equal?", && asks "are BOTH true?"Math Operators
+ - * / % (remainder) ** (power)
Comparison Operators (return true/false)
=== equal, !== not equal, > < >= <=
=== (strict equal), never ==. The double-equals does weird type conversion: "5" == 5 is true, but "5" === 5 is false.Logical Operators
&& AND (both must be true), || OR (at least one true), ! NOT (flips true/false)
Conditionals (if/else)
Conditionals let your code make decisions. The code checks if something is true, then runs different code based on the answer.
This is how auth.js works: if (passwordMatches) { return token } else { return error }
if() is always evaluated to true or false. If true, the first block runs. If false, the else block runs.Loops
for loops run a fixed number of times. while loops run until a condition is false.
Every time BLOOM's brain cycles through 35 agents — that's a loop. Every time Centsable renders 16 domain cards — that's a loop.
for loop has 3 parts: for (start; condition; step). Start: where to begin. Condition: keep going while true. Step: what to do after each cycle.Functions
A function is a reusable block of code. You define it once, then call it whenever you need it.
Functions can take inputs (parameters) and return an output (return value).
Every Netlify Function (auth.js, data.js, penny.js) IS a function — it takes a request as input and returns a response as output.
function greet(name) {} (classic) and const greet = (name) => {} (arrow function). Arrow functions are shorter and used in modern code.Arrays
An array is an ordered list of values. Arrays use square brackets [] and items are separated by commas.
Index starts at 0, not 1. The first item is array[0].
SELECT * FROM users, the result comes back as an array of row objects. Every list you display in your apps is an array.Objects
An object stores data as key-value pairs inside curly braces {}.
Access values with object.key (dot notation) or object["key"] (bracket notation).
{ id: 1, email: "jamal@...", role: "teacher" }. JSON (the format APIs use) IS JavaScript objects.Array Methods
map = transforms each item. filter = removes items that don't pass inspection. reduce = combines everything into one result.Array methods are functions that operate on every item in an array. They're the most powerful tools in JavaScript.
HTML & The DOM
HTML = the structure of a webpage. Tags like <div>, <p>, <button> define elements.
DOM (Document Object Model) = the browser's live representation of the HTML. It's a tree of objects you can manipulate with JavaScript.
Your entire Centsable app is one HTML file. Every view, every quiz, every animation — all created by JavaScript manipulating the DOM.
document.getElementById("x") finds an element. element.innerHTML changes its content. element.style.color changes its look. That's 80% of DOM work.CSS Basics
CSS (Cascading Style Sheets) controls how elements look. Colors, sizes, spacing, layout, animations.
CSS Variables (var(--name)) are how this guide's dark mode works — one toggle changes every color at once.
Events
Events fire when something happens: clicks, key presses, form submits, page loads, scrolls.
You listen for events with element.addEventListener("click", handler).
Every button in your apps uses events. The "Run" button on this page? onclick="runCode('m13')" — that's an event handler.
e) contains details: what was clicked, where the mouse was, which key was pressed. Access it as the first parameter of your handler function.DOM Manipulation
DOM manipulation is how single-page apps work. Instead of loading new pages, you create, modify, and remove elements with JavaScript.
This is how Centsable's showView() works — it doesn't load a new page, it hides one div and shows another.
document.createElement("div") creates an element. parent.appendChild(child) adds it to the page. element.remove() deletes it. element.innerHTML = "..." replaces its contents.Async & Promises
JavaScript is single-threaded — it does one thing at a time. But it can START tasks and come back to them later. This is called asynchronous code.
A Promise is a placeholder for a future value. It's either pending, resolved (success), or rejected (error).
async/await makes Promises readable. await pauses until the Promise resolves.
awaits the response. When auth.js queries the database, it awaits the result. Without async, your app would freeze while waiting.APIs & fetch()
An API (Application Programming Interface) is a URL that accepts requests and returns data.
fetch() is JavaScript's built-in way to call APIs. It returns a Promise.
Every interaction between your frontend and backend is a fetch call. Browser fetches /.netlify/functions/auth, server responds with JSON.
GET = read data, POST = send data, PUT = update data, DELETE = remove data. Your auth.js uses POST (sending login credentials).Error Handling
try/catch prevents the whole app from crashing.try { risky code } catch (error) { handle it } — wraps code that might fail.
Without error handling, one bad API call crashes everything. With it, you show a friendly message instead.
{ statusCode: 500, body: "Server error" }.The Full Stack
Your Actual Stack
Frontend = HTML/CSS/JS in the browser (your PWA files)
Backend = Netlify Functions OR DigitalOcean Express.js
Database = Neon PostgreSQL (stores everything)
APIs = OpenAI, Stripe, Twilio, Coinbase, etc.
Request Flow: User Signs Into Centsable
/.netlify/functions/auth with email + password2. Netlify spins up a container, runs auth.js
3. auth.js connects to Neon:
SELECT * FROM users WHERE email = ?4. bcrypt compares password hash
5. If valid: creates JWT, returns it to browser
6. Browser stores JWT in localStorage
7. All future requests include JWT in Authorization header
That's it. Every app in your empire follows this exact same pattern.
Git & Version Control
Git tracks changes to your files. Every save point is a commit. Every separate line of work is a branch.
Key Commands
git status — What changed?
git add file.js — Stage changes for commit
git commit -m "message" — Save a snapshot
git push — Upload to remote (GitHub/Netlify/DO)
git pull — Download latest changes
git branch feat/new-thing — Create a parallel universe
git add . && git commit && git push. That pushes code to Netlify, which auto-deploys. That's CI/CD (Continuous Integration/Deployment) — push code, it goes live.Deployment
Your Two Deployment Paths
Netlify (Centsable, AA, DQC, ATLAS, RCLL): git push triggers auto-deploy. Files in public/ become a website. Files in netlify/functions/ become serverless APIs.
DigitalOcean (MarketSapien): doctl apps create-deployment builds a Docker container and deploys it. Always-on server running Express.js.
DigitalOcean = Always-on server (runs 24/7, needed for BLOOM's 30-second brain cycle)
Both connect to the SAME Neon PostgreSQL database.
Your Stack — The Complete Picture
The BLOOM Empire Architecture
Every Concept You Learned, In Action
Variables — Environment variables store API keys
Functions — Every Netlify Function IS a function
Objects — Every database row, every API response
Arrays — Lists of students, modules, agents
Async/Await — Every database query, every API call
Events — Every button click, every webhook
Error Handling — Every try/catch in your functions
The Full Stack — Frontend + Backend + Database + APIs
You built all of this. Now you understand HOW it works.
Reading & Debugging Code
Before you can write code, you need to read code. Most of your time as a developer is reading, not writing. Here's how to decode any code you see.
The 4-Step Reading Method
1. Find the entry point — Where does execution start? In a Netlify Function it's exports.handler. In a browser it's the <script> tag or DOMContentLoaded.
2. Follow the data — What comes in? What goes out? Trace the input through each transformation.
3. Identify patterns — Is this a loop? A conditional? A function call? An API request?
4. Read the error — Error messages tell you exactly what's wrong and where. The line number is your GPS.
Common Error Types
ReferenceError: x is not defined — You used a variable that doesn't exist. Typo?TypeError: Cannot read properties of undefined — You tried to access .something on a value that's undefined. Check the chain.SyntaxError: Unexpected token — Your code has a typo. Missing bracket, comma, or quote.404 Not Found — The URL/endpoint doesn't exist. Wrong path.500 Internal Server Error — The server code crashed. Check the function logs.
.find() callback uses = (assignment) instead of === (comparison). This always returns the first user!user is undefined (not found), then user.passwordHash crashes. Add: if (!user) return { statusCode: 401, ... }try/catch. If someone sends invalid JSON, JSON.parse throws and your function crashes with a 500.Build Something from Scratch
The Process: Blank Screen to Working Code
1. Define the goal in plain English — "I need a function that takes a list of students and returns the ones below 50%"
2. Identify the inputs and outputs — Input: array of student objects. Output: filtered array.
3. Write the skeleton — Function signature, parameter names, return statement.
4. Fill in the logic — One line at a time. Run after each change.
5. Test edge cases — What if the array is empty? What if all students pass?
generateReport(students) that takes an array of student objects and returns a report object with: total (count), average (mean score), atRisk (names of students below 50), honors (names of students above 90).
function generateReport(students) { return { total: 0, average: 0, atRisk: [], honors: [] }; } then fill in each field.students.reduce((sum, s) => sum + s.score, 0) / students.length. Round with .toFixed(2).function generateReport(students) {
const total = students.length;
const average = +(students.reduce((sum,s) => sum+s.score, 0) / total).toFixed(2);
const atRisk = students.filter(s => s.score < 50).map(s => s.name);
const honors = students.filter(s => s.score > 90).map(s => s.name);
return { total, average, atRisk, honors };
}handleApiResponse(response) that: if response.statusCode is 200, return the parsed body. If 401, return { error: "Please log in" }. If 500, return { error: "Server error, try again" }. For anything else, return { error: "Unknown error" }. Wrap in try/catch for bad JSON.
function handleApiResponse(r) {
try {
if (r.statusCode === 200) return JSON.parse(r.body);
if (r.statusCode === 401) return { error: "Please log in" };
if (r.statusCode === 500) return { error: "Server error, try again" };
return { error: "Unknown error" };
} catch(e) { return { error: "Bad response: " + e.message }; }
}Commanding Claude Code
The Founder-Engineer Model
You are NOT just a coder. You are a technical founder who commands AI to build at 10x speed. Your job:
2. STRUCTURE how it should be built (architecture decisions)
3. COMMAND the AI to build it (effective prompts)
4. VERIFY the output (code review, testing)
5. ITERATE until it's right (feedback loop)
Writing Effective Commands
Bad prompt: "Fix the login" — too vague, AI guesses wrong
Good prompt: "In auth.js, the login function returns 500 when the user doesn't exist instead of 401. The issue is line 23 — user.passwordHash crashes when user is null. Add a null check before the password comparison."
The SPEC Framework for AI Commands
Situation — What file, what function, what's the current state
Problem — What's wrong or what's missing
Expectation — What the result should look like
Constraints — What NOT to change, performance limits, patterns to follow
Real Commands That Work
"In netlify/functions/data.js, add a new action called 'get_classroom_stats'
that queries the student_progress table grouped by classroom_id,
returns { classroomId, avgScore, totalStudents, atRiskCount }.
Follow the same pattern as the existing 'get_progress' action.
Use the existing db connection from line 5."
"The /api/billing endpoint returns 404 in production but works locally.
I'm on DigitalOcean App Platform with LEAN_STARTUP=true.
Check if the billing routes are mounted in routes-lite.ts
(the production route file). The full routes are in routes.ts."
"I need to add Stripe subscriptions to Adulting Academy.
It's a Netlify site with serverless functions and Neon PostgreSQL.
The existing apps (Centsable, MarketSapien) already have Stripe.
Show me the plan before writing code. I want:
- A billing.js Netlify Function
- A migration for subscription data
- Webhook handling for payment events
Follow the pattern in CentSable-App/netlify/functions/auth.js
for the function structure."
Agent Clusters: Parallel AI Teams
One AI agent is powerful. Multiple agents working in parallel on non-overlapping files is an army. This is how you built your entire empire:
Communication: Through contract files, not chat.
Merge Order: Backend first, content second, UI third.
Your role: Architect (define zones) → Dispatch (launch agents) → Integrate (merge results)
Agent Architecture
What IS an AI Agent?
An agent is an AI with a specific job, tools to do it, and rules about when to act. It's not just a chatbot — it can read databases, call APIs, send emails, and make decisions.
BLOOM's 3-Tier Hierarchy
Agent Communication: The Bus Pattern
Agents don't talk to each other directly. They publish signals to a shared bus. Other agents subscribe to signals they care about.
agentBus.publish("venture_revenue", { app: "Centsable", amount: 500 })
agentBus.subscribe("venture_revenue", "BooksAgent", handler)
Building Your Own Agent
Every agent needs 4 things:
2. Tools — What it CAN do (read DB, call API, send email)
3. Decision Logic — When to act, when to escalate
4. Memory — What it remembers between cycles
VentureTracker agent that subscribes to "venture_milestone" signals, keeps a running count of milestones per app, and publishes a "venture_report" signal when any app hits 5 milestones.
const counts = {} to track milestones per app. In the handler: counts[data.app] = (counts[data.app] || 0) + 1const counts = {};
bus.subscribe("venture_milestone", "VentureTracker", (data) => {
counts[data.app] = (counts[data.app] || 0) + 1;
console.log("[VT] " + data.app + ": " + data.milestone + " (#" + counts[data.app] + ")");
if (counts[data.app] === 5) bus.publish("venture_report", { app: data.app, count: 5 });
});Economics of AI Development
Your Actual AI Costs
| Service | Model | Cost | Speed | Use Case |
|---|---|---|---|---|
| OpenAI | GPT-4o-mini | $0.15/1M input | Fast | PENNY, ARIA tutors, quick tasks |
| Anthropic | Claude Opus | $15/1M input | Slow | BLOOM deep reasoning (every 30s) |
| Anthropic | Claude Sonnet | $3/1M input | Medium | BLOOM voice, moderate tasks |
| Ollama | Llama 3.1 8B | $0 (local) | 22 tok/s | Quick agent tasks, drafts |
| Ollama | Qwen 2.5 32B | $0 (local) | 5.4 tok/s | Near-frontier quality, free |
The Cost Hierarchy: When to Use What
Cheap (GPT-4o-mini): User-facing tutors, simple Q&A, content generation
Medium (Sonnet): Code generation, voice interactions, analysis
Expensive (Opus): Complex reasoning, strategic decisions, BLOOM's brain
Rule: Use the cheapest model that gets the job done. Start cheap, upgrade only when quality demands it.
Your Infrastructure Math
| Service | Monthly Cost | What You Get |
|---|---|---|
| Netlify | $0 | 6 sites, 125K function calls |
| Neon PostgreSQL | $0 | Database for ALL apps |
| DigitalOcean App | $12 | MarketSapien backend (24/7) |
| DO Droplet | $6 | Telegram bots server |
| DO Spaces | $5 | Media CDN (250GB) |
| OpenAI usage | $5-20 | AI tutors + BLOOM reasoning |
| Stripe fees | 2.9% + $0.30/txn | Only when you make money |
| TOTAL | $28-43/mo | 6 live apps, 35 agents, full stack |
Revenue vs. Cost: The Math That Matters
Your burn: ~$9,563/month (personal expenses). Your infrastructure: ~$35/month.
The infrastructure is NOT your problem. Getting to revenue is. One MarketSapien subscription at $14.99/mo pays for your entire cloud infrastructure.
Break-even on personal burn: ~640 MarketSapien subscriptions OR 3 school deals
Fastest to revenue: MarketSapien (Stripe already built) > DQC (RedBubble passive) > Adulting Academy (Stripe sprint)
Your Playbook: Code + AI + Revenue
The Technical Founder Stack
1. Read code well enough to spot bugs and understand architecture
2. Write small functions when needed (50-100 lines max)
3. Command AI agents with clear SPEC prompts to build features
4. Design systems: what talks to what, how data flows
5. Verify output: test, review, catch errors before they hit users
Your Daily Workflow
Morning: Check ATLAS World dashboard. What signals fired overnight? Any revenue events?
Build Session: Pick the highest-priority task. Write a SPEC command. Launch agent(s). Review output.
Revenue Focus: Every build session should move one app closer to money. If it doesn't generate or enable revenue, deprioritize it.
Evening: BLOOM runs autonomously. Check Telegram for overnight reports.
The Commands You'll Use Most
What You Learned (27 Modules)
Foundations (1-10): Variables, types, operators, conditionals, loops, functions, arrays, objects, array methods — the building blocks of all code.
Browser (11-14): HTML, CSS, DOM, events — how your PWAs work.
Real World (15-21): Async, APIs, errors, full stack, git, deployment, your architecture.
Intensive (22-27): Debugging, writing from scratch, commanding AI, agent systems, economics, this playbook.
You are a technical founder who commands AI armies to build empires. Go make money.
Strings & Text
A string is a sequence of characters. Template literals — backtick strings — let you embed a value with ${...} instead of gluing pieces with +, which is easier to read and much harder to get wrong.
Worked example
const name = "Ada";
console.log(name.length); // 3
console.log(name.toUpperCase()); // "ADA"
console.log(`Hello, ${name}!`); // "Hello, Ada!"
Scope & Closures
Scope is the region where a name is visible. An inner function can see its outer function's variables, and it keeps seeing them even after the outer function has finished. That surviving connection is a closure — it is how a function can remember something between calls.
Worked example
function makeCounter() {
let count = 0; // lives in makeCounter's scope
return function () {
count = count + 1; // the inner function REMEMBERS count
return count;
};
}
const next = makeCounter();
console.log(next()); // 1
console.log(next()); // 2 — count survived
Forms & Input
Read a field with element.value. Validate before you act. Call event.preventDefault() on submit so the browser does not reload the page and throw your work away.
Worked example
const value = " ada@example.com ";
const cleaned = value.trim(); // remove stray spaces first
if (cleaned === "") {
console.log("Please enter an email.");
} else if (!cleaned.includes("@")) {
console.log("That does not look like an email.");
} else {
console.log("Thanks! We saved " + cleaned);
}
Layout — Flexbox & Grid
display:flex arranges children along one axis; justify-content positions them along it and align-items across it. display:grid defines explicit tracks with grid-template-columns. Centring, famously hard in old CSS, is two lines in either.
Worked example
/* one row, evenly spread, vertically centred */
.toolbar { display: flex; justify-content: space-between; align-items: center; }
/* three equal columns that wrap on small screens */
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; }
JSON & Data Shapes
JSON is text that describes objects and arrays. JSON.parse turns text into values you can use; JSON.stringify turns values back into text. Optional chaining (?.) reads a nested field without crashing when part of the path is missing.
Worked example
const text = '{"data":{"amount":"64821.37","currency":"USD"}}';
const obj = JSON.parse(text);
console.log(obj.data.amount); // "64821.37"
console.log(obj.data.symbol); // undefined — missing, but no crash
console.log(obj.meta?.page); // undefined — ?. stops the crash
Storage & State
localStorage.setItem(key, text) saves; getItem(key) reads and returns null when nothing is there. Because it stores text only, wrap objects with JSON.stringify and unwrap with JSON.parse.
Worked example
const progress = { module: "m33", done: true };
const asText = JSON.stringify(progress); // '{"module":"m33","done":true}'
const back = JSON.parse(asText); // an object again
console.log(back.module); // "m33"
console.log(JSON.parse("null") === null); // true — "nothing saved yet"
Debugging Tools
Debugging is narrowing. Reproduce it reliably, read the message and the stack, then bisect — check a value halfway through and decide which half holds the fault. Repeat until the space is one line. console.log is a real debugger; a breakpoint is a faster one.
Worked example
function averageOf(numbers) {
let total = 0;
for (const n of numbers) total = total + n;
return total / numbers.length;
}
console.log(averageOf([2, 4, 6])); // 4 — good
console.log(averageOf([])); // NaN — a bug: 0 / 0
// Narrowing: total is 0, length is 0, so the fault is the empty case.
Testing Basics
A test gives an input, states the expected output, and reports pass or fail. That is the whole idea — frameworks add convenience, not meaning. Test behaviour, not implementation, so the test survives a rewrite.
Worked example
function check(label, actual, expected) {
const ok = actual === expected;
console.log((ok ? "PASS " : "FAIL ") + label + " got: " + actual);
return ok;
}
check("2 + 2", 2 + 2, 4); // PASS
check("empty average", 0, 0); // PASS
Reading Documentation
Read a signature before an example: what goes in, what comes out, what is optional. Then check the edge notes — what happens with no arguments, or with the wrong type. Prefer the primary source: MDN and the official language docs over an aggregator.
Worked example
// A signature tells you the contract before you write a line:
// arr.slice(start, end) -> a NEW array, from start up to but NOT including end
const letters = ["a", "b", "c", "d"];
console.log(letters.slice(1, 3)); // ["b","c"] — end is excluded
console.log(letters); // unchanged — slice does not modify