Appearance
JavaScript and TypeScript Course Curriculum
This course is a sequence of long-form technical articles for an experienced developer who can already read JavaScript but wants enough command of its syntax, semantics, environments, conventions, and ecosystem to write JavaScript and TypeScript confidently.
The course begins with JavaScript as a runtime language. TypeScript is added only after the JavaScript object model, modules, errors, and asynchronous execution are familiar. Browser programming comes before React so JSX, TSX, framework behavior, and Web APIs remain distinguishable.
The writing style is defined in ARTICLE_GUIDE.md. The article-review and maintenance approach is described in TOOLCHAIN.md.
Learning format
The entire learning experience is a connected collection of articles with examples embedded directly in the prose. Articles should feel like strong chapters in a technical book rather than standardized lessons.
There are no assignments, per-article exercises, external example files, prediction worksheets, or completion checklists. Readers may type and modify examples when curiosity calls for it, but the course does not require project work to progress.
When several concepts need to be seen together, an article can develop an extended case study through a sequence of embedded snippets. The prose remains responsible for explaining the design, the tradeoffs, and how the parts interact.
Course shape
The course has six parts and twenty-one planned articles:
- JavaScript as a language and runtime
- Values, functions, objects, and collections
- Modules, errors, and asynchronous programs
- TypeScript
- Browser JavaScript
- JSX, TSX, React, and the broader ecosystem
The article list is a content plan rather than a promise that every heading becomes exactly one file. Closely related articles may be combined during writing, and an unusually dense topic may be divided.
Part 1: JavaScript as a language and runtime
Article 1: What JavaScript actually is
This opening article establishes the layers routinely conflated under the word “JavaScript.”
It covers:
- ECMAScript as the language.
- Engines such as V8, JavaScriptCore, and SpiderMonkey.
- Host environments such as browsers, Node.js, Bun, and Deno.
- Host-provided globals and APIs.
- Libraries and frameworks.
- JavaScript versus TypeScript, JSX, and TSX.
- How to identify which layer owns an unfamiliar construct.
The reader should leave able to ask the right documentation and compatibility question when encountering an API.
Article 2: Running JavaScript
This article explains the practical path from a source file to a running program.
It covers:
- Running a file and using a REPL.
- Node.js as the course's baseline environment.
- Browser scripts and modules at a conceptual level.
- Command-line arguments, standard input, standard output, and process exit.
package.json, package scripts, and the meaning of"type": "module".- Dependencies, development dependencies, and lockfiles.
- Why a package manager, runtime, compiler, test runner, and bundler are separate roles even when one product combines them.
- A first comparison of Node.js and Bun.
Part 2: Values, functions, objects, and collections
Article 3: Values, variables, and everyday syntax
This is a compact tour of the syntax needed to begin writing modern JavaScript.
It covers:
- Statements and expressions.
const,let, and recognition ofvar.- Primitive types.
- Template literals.
- Arithmetic, comparison, conditional, and logical operators.
- Blocks and basic control flow.
for,for...of, and recognition offor...in.- Function calls and property access.
- Optional chaining and nullish coalescing at an introductory level.
The article moves quickly through familiar constructs and slows down for JavaScript-specific semantics: number, NaN, infinities, negative zero, null, undefined, and the difference between a constant binding and immutable data.
Article 4: Equality, coercion, and absence
This article develops the rules that frequently cause subtle boundary and configuration bugs.
It covers:
- Strict equality and inequality.
- Recognition and limited intentional uses of loose equality.
- Object identity.
- Truthy and falsy values.
- Logical operators returning operands.
||versus??.- Explicit conversion with
String,Number, andBoolean. typeof,Array.isArray,Number.isNaN, andNumber.isFinite.- Choosing a representation for missing, empty, and invalid values.
Examples use configuration, form, and JSON-like data rather than isolated coercion puzzles.
Article 5: Objects, arrays, maps, and sets
This article explains JavaScript's everyday data structures as a connected toolkit.
It covers:
- Object and array literals.
- Reference identity and mutation.
- Dot and bracket property access.
- Computed properties and property shorthand.
- Destructuring.
- Rest and spread syntax.
- Shallow copying and aliasing.
- Array iteration and transformation methods.
MapandSet.- When a plain object is a record and when
Mapis a better collection. - Enumeration with
Object.keys,Object.values,Object.entries, andObject.fromEntries. - Immutability as a design choice rather than an automatic language guarantee.
The article discusses readability tradeoffs between loops and chains of map, filter, flatMap, and reduce without presenting functional-looking code as inherently superior.
Article 6: Functions, scope, and closures
This article treats functions as the center of ordinary JavaScript design.
It covers:
- Function declarations, expressions, and arrow functions.
- Parameters, defaults, rest parameters, and return values.
- Functions as values.
- Callbacks and higher-order functions.
- Lexical scope and block scope.
- Closures and captured bindings.
- Hoisting and the temporal dead zone to the extent needed for real code.
- Module-private and closure-private state.
- When a closure factory is simpler than a class.
Article 7: this, prototypes, and classes
This article explains JavaScript's object model without making prototypes seem mystical or requiring manual prototype programming for everyday work.
It covers:
- How call form determines
thisfor ordinary functions. - Why extracting a method can lose its receiver.
- Lexical
thisin arrow functions. call,apply, andbindfor recognition and occasional use.- Prototype-based property lookup.
- Classes as syntax over prototype delegation.
- Constructors, instance methods, static members, inheritance, and
super. - Public fields and
#privatefields. - Composition, classes, plain objects, and closure factories as design options.
Part 3: Modules, errors, and asynchronous programs
Article 8: Modules and program structure
This article should explain ECMAScript modules as both syntax and an architectural boundary.
It should cover:
- Named and default exports.
- Static imports, dynamic imports, and re-exports.
- Module scope and live bindings.
- Entry points and public APIs.
- Relative resolution and file extensions.
- Circular dependencies.
- Side effects during module evaluation.
- Separating domain logic from environment adapters.
- CommonJS recognition and interoperability without using it as the course default.
- File and directory naming conventions.
- How much structure a small program actually needs.
An extended reporting-program case study can gradually separate parsing, domain behavior, formatting, and an executable entry point entirely within the article.
Article 9: Errors, validation, and boundaries
This article should distinguish different failure categories rather than presenting try and catch as generic error handling.
It should cover:
- Throwing and catching.
Error, subclasses, stacks, andcause.- Cleanup with
finally. - Programmer errors versus expected invalid input.
- Exceptions versus result objects.
- Adding context while preserving the original failure.
- Designing errors at filesystem, network, parsing, and domain boundaries.
- Testing failure behavior conceptually.
The reporting case study can demonstrate why static expectations never make external JSON valid by themselves.
Article 10: Promises and asynchronous control flow
This article explains promises from their semantics upward rather than treating async and await as magical syntax.
It should cover:
- Callbacks and completion.
- Promise states and chaining.
- Resolution, rejection, and flattening.
asyncfunctions andawait.- Sequential versus concurrent work.
Promise.all,allSettled,race, andany.- Error propagation.
- Avoiding unnecessary promise construction.
- Common missing-return and unhandled-rejection bugs.
Examples should make work-start timing visible and distinguish creating a promise from awaiting it.
Article 11: The event loop, cancellation, and async design
This article develops the execution model needed to reason about real asynchronous programs.
It should cover:
- The call stack.
- Tasks and microtasks.
- Timers and promise callbacks.
- Event-loop ordering.
- Single-threaded concurrency and race conditions.
AbortControllerandAbortSignal.- Timeouts, retries, and cleanup.
- Concurrency limits.
- Async iterables and streams at an introductory level.
- When worker threads or another form of parallelism would actually be relevant.
A bounded job-processor case study can integrate concurrency limits, stable results, cancellation, retry, and progress callbacks without becoming a reader assignment.
Part 4: TypeScript
Article 12: What TypeScript adds—and what it cannot add
This article introduces TypeScript as a static model layered over JavaScript.
It should cover:
- Type inference and annotations.
- Type erasure.
- Primitive, object, array, tuple, and function types.
- Optional and read-only properties.
any,unknown,never, andvoid.- Type assertions and why they do not validate data.
- The relationship between
.js,.ts, compiled output, and direct type stripping. - The role of
tsconfig.json.
The central theme is that JavaScript runtime knowledge remains necessary. TypeScript should sharpen that knowledge rather than conceal it.
Article 13: Structural types and narrowing
This article develops TypeScript's everyday modeling tools.
It should cover:
- Type aliases and interfaces.
- Structural compatibility.
- Union and intersection types.
- Literal types.
- Control-flow narrowing.
typeof,instanceof, property checks, and equality narrowing.- Discriminated unions.
- Exhaustive switches and
never. - Type predicates and assertion functions.
- Modeling states instead of accumulating optional fields and boolean flags.
Examples should follow external data through validation into a trusted internal model and show a state machine represented by a discriminated union.
Article 14: Generics and type relationships
This article should explain generics as relationships between types rather than placeholder syntax.
It should cover:
- Generic functions and object types.
- Inference.
- Constraints.
keyof, indexed access, andtypeofin type positions.- Mapped and conditional types.
- Standard utility types.
- Template literal types where genuinely useful.
- Reading library signatures.
- Recognizing over-generalized or unnecessarily clever types.
The examples can progress from a generic collection helper to a typed message map where names determine payload and result types.
Article 15: TypeScript projects and library boundaries
This article covers the mechanics required to work in real TypeScript repositories.
It should cover:
- Important
tsconfigoptions. - Target versus runtime.
- Module format versus module resolution.
- Strictness options.
- Type-only imports.
- Declaration files and
@typespackages. - Application
noEmitworkflows versus compiling a distributable library. - Source maps.
- Interoperating with JavaScript and CommonJS packages.
- Runtime validation libraries as an ecosystem concept without making one mandatory.
A typed message-processing library can serve as the integrated case study, including public types, runtime validation, declaration output, and consumer usage.
Part 5: Browser JavaScript
Article 16: The browser as a JavaScript host
This article reuses the opening language-versus-host model in a browser context.
It should cover:
- HTML and the DOM tree.
- Selecting, creating, changing, and removing elements.
- Attributes versus properties.
- Text insertion versus HTML insertion.
- Events, bubbling, capturing, and delegation.
- Forms and
FormData. - Focus, keyboard interaction, and basic accessibility.
- Browser developer tools.
- Browser module loading.
Examples should build one small interface progressively within the article rather than scattering unrelated DOM snippets.
Article 17: Browser data, networking, and state
This article should cover:
fetch, requests, responses, and status handling.- JSON boundaries and validation.
- URLs and query parameters.
- Cancellation and stale requests.
- Same-origin policy and CORS conceptually.
localStorage, session storage, and IndexedDB at the appropriate depth.- Loading, empty, error, and stale states.
- Keeping URL, persistent preference, and in-memory state distinct.
A framework-free searchable catalog can grow through the article as an integrated case study, connecting data loading, filtering, URL state, persistence, and accessible interactions.
Part 6: JSX, TSX, React, and the ecosystem
Article 18: JSX and component rendering
This article should carefully separate several layers:
- JavaScript expressions.
- TypeScript annotations.
- JSX syntax.
- React component conventions.
- Browser DOM behavior.
It should cover:
- JSX as transformed syntax.
- Elements, components, props, and children.
- JSX differences from HTML.
- Expressions inside markup.
- Conditional and list rendering.
- Keys.
- Component composition.
- Pure rendering.
- How JSX ultimately becomes JavaScript values and calls.
The article should occasionally classify parts of a TSX snippet by layer, but it should remain a narrative rather than a worksheet.
Article 19: React state, events, and effects
This article should cover:
- Rendering and state snapshots.
- State updates, including updates based on previous state.
- Controlled inputs.
- Lifting and deriving state.
- Immutable updates.
- Event handling.
- Effects as synchronization with external systems.
- Dependency arrays, cleanup, and stale closures.
- Refs.
- Recognizing when an effect is unnecessary.
Any comparison with SwiftUI should be limited to places where superficial similarity could produce the wrong model.
Article 20: Typed React and application structure
This article should cover:
- Typing component props and events.
- Optional, conditional, and discriminated-union props.
children.- Generic components where they preserve a useful relationship.
- Context at an introductory level.
- API boundaries and runtime validation.
- Component tests and user-oriented queries conceptually.
- Client rendering, server rendering, static generation, and server components conceptually.
- The difference between React itself and a full-stack React framework.
The framework-free catalog from Part 5 can be revisited in React and TSX so the article can compare what remains ordinary language and browser logic with what the framework changes.
Article 21: The modern JavaScript toolchain
This final article places the surrounding tools into a coherent map.
It should cover:
- npm, pnpm, and Bun's package manager.
- Semantic versioning and lockfiles.
- ESLint and type-aware linting.
- Prettier.
- Vitest and Node's test runner.
- Testing Library and browser automation.
- Vite, bundling, source maps, tree shaking, and code splitting.
- Workspaces.
- CI.
- How to choose a runtime and toolchain for a CLI, library, browser application, full-stack application, or short script.
Tools should be introduced as solutions to specific problems, not as a checklist every project must adopt.
Approximate pacing
| Part | Estimated reading and exploration |
|---|---|
| JavaScript and runtime foundations | 5–7 hours |
| Values, functions, and objects | 14–20 hours |
| Modules and asynchronous programs | 10–15 hours |
| TypeScript | 12–18 hours |
| Browser JavaScript | 7–10 hours |
| React, TSX, and ecosystem | 12–18 hours |
The course should be maintained as a continuous sequence. Revisions should check for repetition, missing transitions, and examples that accidentally assume material from a later article.