Foundations: Product, Code and the Working Environment
Anatomy of a Code Project: How to Read a Repository Without Getting Lost
How a program is laid out on disk, how to tell source code from configuration, dependencies and generated files, how to read a small piece of JavaScript,…
In A Map of Digital Product Development we followed a client from the "Book" button to a server program and a saved time slot. Now let us look at the other side: which files make up such a program, where its rules live, and how to tell what exactly an agent has changed.
What you will understand
By the end of this unit you will be able to explain how a program is laid out on disk, tell source code apart from configuration, dependencies and generated files, and read a small piece of JavaScript and describe what it does. You do not need to write or run code yourself. Running commands is covered separately in Terminal, Local Environment and Program Execution, and the history of changes in Git: History, Branches and Safe Changes.
The booking examples below are invented for teaching. All code and configuration snippets are illustrative: they were not run or tested here in any real project.
Find the project's map first
A repository is a folder containing a project's files plus the data a version control system, such as Git, needs to keep track of changes. In team work a repository often holds code, documentation, checks and configuration, but there is no rule that every project must contain the same set of folders.
A directory is another word for a folder. A path shows how to reach a file through the folders: for example, src/booking.js. An extension is the last part of a file name after the dot, such as .js or .md. It is a useful hint about the format, but the name alone does not guarantee that the content really is in that format. The .md extension usually marks Markdown, a text format with simple markup.
A README is a file with a name like README.md that usually explains what the project is for, how to use it, where to get help and what you need to know before making changes. It is a good first stop, not a complete and guaranteed-current specification. GitHub's documentation describes the README as the place for the project's purpose, why it is useful, how to get started and where to get support (GitHub Docs).
A module is a part of a program with its own names and visibility boundaries, which can expose selected functions or values to other parts. In JavaScript, modules often correspond to individual files that use export and import; in other languages the module boundary may take a different form.
An entry point is the file or command from which a particular environment starts loading the program. It may be defined in a start-up script or in a tool's settings; not every project starts from index.js. In Node.js, the main and exports fields of the manifest describe the package's entry points for importing, which is not necessarily where the whole application starts (Node.js: Modules: Packages).
The tree below includes JSON (JavaScript Object Notation), a text format for structured data, and YAML (a recursive acronym for "YAML Ain't Markup Language"), which is often used for configuration (ECMA-404, YAML 1.2.2). HTML (HyperText Markup Language) defines the structure of a web page, and CSS (Cascading Style Sheets) its appearance (MDN (originally the Mozilla Developer Network, now MDN Web Docs): Creating the content, MDN: What is CSS?).
Here is a possible, but not universal, tree for a small booking service:
booking-demo/
├── README.md
├── package.json
├── package-lock.json
├── .gitignore
├── .env.example
├── src/
│ ├── app.js
│ ├── booking.js
│ └── booking-form.js
├── docs/
│ └── booking-rules.md
├── tests/
│ ├── booking.test.js
│ └── samples/
│ └── busy-times.json
├── scripts/
│ └── build.js
├── config/
│ └── local.yaml
├── migrations/
│ └── 001-create-bookings.migration
├── public/
│ ├── index.html
│ └── styles.css
├── assets/
│ └── logo.txt
├── dist/
│ └── app.bundle.js
└── .cache/
Each line shows only a possible role:
srcis short for "source". It may hold the code the team maintains by hand.docsholds explanations for people: booking rules, decisions, instructions or constraints.testsholds checks of the expected behaviour;samplesin this example is test data, not product code.scriptsholds helper programs for repetitive tasks, such as preparing files. A file's name does not prove the command is safe: a script can do anything at all.configholds settings. Some settings may sit next to the code; others may come from the environment the program is launched in.migrationsoften stores the steps for moving between versions of the data structure. Their order, and running them more than once, can have consequences, so they are not ordinary drafts.public, in a web project, may contain material the browser can fetch directly. In the example,index.htmluses HTML for the page structure andstyles.cssuses CSS for its look. Other projects may keep client-side code in other directories.assetsholds static material such as fonts, icons or images. The teaching tree uses a placeholder text file rather than a real image.distis usually short for "distribution", meaning output prepared for distribution. In the example,app.bundle.jsis produced by the build script; it is not the original to edit..cacheis a cache: temporary data that a tool can regenerate. Its contents cannot always be deleted without consequences; first find out what creates it and why.
Files whose names start with a dot are often hidden in an ordinary folder view. .gitignore describes which not-yet-tracked files Git should ignore. It is not a universal way to remove secrets: if a file has already been added to the repository, listing it in .gitignore does not stop Git from tracking it (GitHub Docs: Ignoring files). .env.example may show the names of the expected settings with safe sample values, but it does not confirm how the application actually loads them.
The structure tells you where things might live, but it does not prove the architecture. A services folder, for example, may contain one program or many; a folder called backend does not explain where the component boundaries are. The rules of one framework (a ready-made set of tools and conventions) do not become rules for every language and every team. Start by checking the README, the configuration files, the build scripts and where code is imported from.
Data, behaviour and small code constructs
A value is a concrete piece of data the program works with. In JavaScript, the string "11:30" is text, 690 is a number, and true and false are Boolean values, that is, "yes" or "no" answers. A string made of digits is still text until it is explicitly converted into a number.
A variable is a named place through which code refers to a value. In JavaScript, a variable is declared with, for example, const or let. const prevents the variable itself from being reassigned; if it refers to an object, that does not necessarily prevent the object's properties from being changed.
A type describes what kind of values a variable holds and which operations make sense for them. In JavaScript the type belongs to the value: the same variable can hold a number on one line and text on another. This differs from languages where static type checking can warn about some mismatches before the program runs. MDN covers basic types, variables, scope and JavaScript's rules in its guide to grammar and types.
An array is an ordered list of values. An object is a collection of values accessed by named properties. Here is a snippet, explained line by line:
const busyStarts = [660, 720];
const booking = {
guestName: "Olena",
startMinute: 690,
};
const displayName = booking.guestName;
busyStartsis an array of numbers, here minutes from the start of the day:660means 11:00 and720means 12:00.bookingis an object with two named properties. ItsguestNamefield holds a string, andstartMinuteholds a number.displayNametakes the value of theguestNameproperty, that is, the string"Olena".
The example does not check whether the booking is real or the slot available: it only shows the shape of the data. In JavaScript, a missing object property usually yields the value undefined; null is a separate, explicit value meaning "nothing here". To understand code, it matters what an absence actually means: an empty field, an unknown search result, or bad data. Trying to read a property of null can fail with a type error at run time, which is why data from an interface is usually validated before it is used.
A function is a named piece of code that can be called. It can receive parameters (input values) and hand back a result with return. Scope determines where declared variables can be accessed from. A local variable inside a function does not automatically become available to the whole program. The conditional statement if chooses which lines to run depending on a condition; a loop, such as for...of, repeats an action for each item in a list. MDN covers functions, conditions and loops in its guide to functions and its guide to control flow.
Here is some code that checks simple availability:
function canBook(startMinute, busyStarts) {
if (typeof startMinute !== "number" || !Number.isFinite(startMinute)) {
return false;
}
for (const busyStart of busyStarts) {
if (startMinute === busyStart) {
return false;
}
}
return true;
}
The function receives a number, startMinute, and an array, busyStarts. It checks startMinute and rejects it if it is not a finite number: that covers null, undefined and a text value such as "690". The code does not check the busyStarts array; it assumes the array contains numbers. Otherwise, the loop compares the chosen time with each busy one. On a match it returns false; if the loop finishes without a match, it returns true. For example, canBook(690, [660, 720]) gives true, canBook(720, [660, 720]) gives false, and canBook(undefined, [660, 720]) gives false.
This snippet is only about an exact match of minutes. It ignores meeting length, working days, time zones, user permissions, and the schedule changing between the check and the save. Here true means only "this condition lets the value through", not "the booking is guaranteed to be saved".
Example: from the button to a saved booking
Situation. An imaginary support ticket says: "The button shows the form, but after clicking it no booking appears."
Reading the tree. In this hypothetical project the path might look like this:
public/index.htmldeclares the button and the form the visitor sees;src/app.jsmay wire the parts of the program together.src/booking-form.jsresponds to the click event, reads the selected time and passes it on.src/booking.jsholds the rules and the save function. A server-side part or some other adapter may forward the request to storage; exactly where that code lives depends on the project.tests/booking.test.jscontains checks and describes the expectations: an available time is accepted, a busy one rejected;tests/samples/busy-times.jsonis sample data for those checks, not program logic.docs/booking-rules.mdexplains the rules to people, andREADME.mdhelps you find general information.scripts/build.jsmay read the source files and producedist/app.bundle.js. In that casesrcis the source anddistis the build output.config/local.yamlshows a possible local setting; the migration file describes a change to the storage structure. These names and roles belong to this teaching example only; they cannot be carried over to someone else's repository without checking. Migrations run in a defined order and can change data, so they should not be treated as ordinary drafts.
A small snippet showing how the files connect, purely for explanation:
// src/booking.js
export function canBook(startMinute, busyStarts) {
return !busyStarts.includes(startMinute);
}
export function saveBooking(startMinute, store) {
return store.save({ startMinute });
}
// src/booking-form.js
import { canBook, saveBooking } from "./booking.js";
function onSubmit(startMinute, busyStarts, store) {
if (!canBook(startMinute, busyStarts)) {
return false;
}
return saveBooking(startMinute, store);
}
export marks that the module makes a function available to other files. import takes it from the given path. In canBook, the includes method asks whether the exact value is in the array, and the ! operator flips the answer: a time counts as available if it is not yet in the list of busy times. The form first asks the canBook rule; if it returns false, onSubmit ends without saving. Otherwise it calls saveBooking, which passes the booking object to an abstract store. Here store.save is a hypothetical storage contract, not a specific server or database. The snippet does not yet prove that the button is connected to onSubmit: to establish the real path of the event, you have to read the code around the button and find where it is called.
What the analysis gives you. Whoever is looking into the ticket does not need to know every line of the program to see where the problem might lie: the visual form, the click handler, the availability rule, the save step and the checks all play different roles. That points to which files are worth investigating and comparing against the requirement.
Alternative and limits. In a project built on server-side templates, or in a mobile app, the path from the button may be completely different. The tree here is a hypothetical map for one example, not a ready-made architecture template. A folder called tests also does not guarantee that the scenario you care about is already being checked.
A data file is not program logic
A data format sets the rules for writing and reading information. Behaviour is the set of rules by which a program makes decisions or takes actions. A setting can change behaviour even though it is not itself program code.
JSON is a widespread text format for structured data. Its standard allows neither comments nor a trailing comma:
{
"port": 4100,
"mode": "preview"
}
Losing the comma between the properties can make the file unreadable for a parser, the program that takes a format apart. As a result, the application may fail to start before any booking business rule ever runs. That is a syntax problem with the format, not a change to the rule about who is allowed to book a slot. JSON's rules are set by a separate Ecma International specification (ECMA-404).
YAML is often used for configuration. Indentation matters in it: it shows nesting.
booking:
reminderMinutes: 30
allowGuest: false
Here reminderMinutes and allowGuest are fields inside booking. If the indentation is accidentally changed, a tool may read a different structure or report an error. The behaviour also depends on how the particular application uses the value it reads. The language's rules are described in YAML 1.2.2.
Markdown is a text format with simple markup for headings, lists, links and code blocks. It helps structure text for a reader, but plain Markdown does not execute a rule like "book it if the slot is free". Different sites support extensions to the common specification, so rendering may differ slightly; CommonMark 0.31.2 describes the basic examples of the format.
Comments also depend on the format. A JavaScript comment, marked with //, is a hint to the reader, not an instruction to the program. YAML has its own comments, marked with #. Standard JSON has no comment syntax at all. Markdown may simply display such a line as ordinary text. Do not copy a comment marker from one file to another without checking the format.
Configuration and environment variables
Configuration is the set of values that determine exactly how to run a program in a particular environment: for example, a local port number, the interface language, or the address of a test service. An environment variable is a named value that the launch environment passes to the program separately from its source code.
.env is a common name for a text file of NAME=value pairs. But the same file format does not guarantee the same behaviour: different languages and tools read it by their own rules. The Node.js documentation states explicitly that there is no single formal specification of .env across platforms, and defines the rules for its own environment (Node.js: Environment Variables).
A setting is not necessarily a secret: APP_PORT=4100 can be ordinary configuration. An API (application programming interface) is an agreed way for one program to ask another for data or an action. A key for an external API, such as PAYMENT_API_KEY, may well be a secret. The line below is just a safe placeholder, not a real key:
APP_PORT=4100
PAYMENT_API_KEY=replace-with-local-secret
A sample .gitignore may list .env, while the repository keeps a .env.example with field names and made-up values. This lowers the risk of accidentally adding the local file, but it does not make the file secure and does not revoke a secret that has already made it into the repository's history. Secrets should be passed only through an agreed, secure channel; do not copy real keys into code, examples or logs.
Packages, versions and lockfiles
A package is a unit of code that can be described and distributed within a particular ecosystem. A package manager is a tool that helps find packages, choose compatible versions and install them. In the examples below this is npm, the package manager of the Node.js ecosystem. Other languages and tools have their own manifests and lockfiles; the file names and rules are not a shared standard.
A manifest is a file holding a project's metadata and its direct requirements. For npm this is usually package.json, a JSON file. A direct dependency is a package the project has declared for its own use. A transitive dependency is a package that one of the direct dependencies depends on. The package manager reconciles all these relationships together.
This is not the whole manifest but an excerpt from the package.json of the open-source library p-limit, version 7.3.3, pinned by a tag. The values are taken from its manifest:
{
"name": "p-limit",
"version": "7.3.3",
"type": "module",
"scripts": {
"test": "xo && ava && tsd"
},
"dependencies": {
"yocto-queue": "^1.2.1"
},
"devDependencies": {
"ava": "^6.4.1",
"in-range": "^3.0.0",
"random-int": "^3.0.0",
"time-span": "^5.1.0",
"tsd": "^0.33.0",
"xo": "^1.2.1"
}
}
name and version name the package and its version. The type field tells Node.js to treat .js files as ECMAScript modules. scripts defines named commands; the test script in this pinned manifest runs xo, ava and tsd in sequence, and the && operator runs the next command only if the previous one succeeded. Scripts like these can execute code, so before running them it is important to check what they are for and where they came from. dependencies lists the direct dependency yocto-queue, and devDependencies lists packages developers need for checks and related work. The split depends on what a user of the package needs versus what is needed only during development, testing or building. npm explains the difference in its documentation on dependencies.
A version entry such as ^1.2.1 is an npm version range requirement, not a claim that all future versions will be equally compatible with a given application. A dependency's version may be incompatible with another library, with the runtime environment, or with the project's expectations. Check the rules of the chosen package manager, the environment requirements and the current tests; do not carry the meaning of ^ or of version schemes over to other ecosystems without checking.
package-lock.json records the dependency tree that npm chose for this project and shows changes to it as a text diff. It is a generated artefact, usually created and updated by the package manager, not a list to be edited freely by hand. A lockfile makes installs more repeatable, but it does not guarantee identical behaviour across npm versions, operating systems, services or environment variables (npm package-lock).
Different kinds of check do not replace each other
Before changing code, it helps to know what question each stage asks:
| Stage | What it can catch | What its result does not prove on its own |
|---|---|---|
| Syntax parsing | Wrong brackets, quotes, commas or keywords | That the business rule meets the client's need |
| Static type checking | Some mismatches between declared types and their uses | That external data has the expected shape, or that the logic is correct |
| Build | Some errors in transforming files, imports or build configuration | That the whole application works correctly in real scenarios |
| Run | Errors that arise in the runtime environment or from missing settings | That untried scenarios work too |
| Behaviour test | The answer to one specific, tested expectation | That every combination of inputs and every external dependency has been checked |
Static type checking analyses values and how they are used before the relevant scenario has run. For example, TypeScript, a language and tool for checking JavaScript programs, can report that a number is being passed where text was declared. But data that arrives from a form or the network can still be wrong: types do not automatically check every actual value. The TypeScript documentation describes it as a static checker; type annotations are erased during transformation and do not become automatic protection at run time (TypeScript Handbook: TypeScript for the New Programmer).
Interpretation and compilation are ways in which tools process code, but a modern environment may combine both. Compilation usually transforms code before or during execution; a build may additionally combine files or generate new ones. Not every program has a separate build step, and a command called build does not, by its name alone, tell you the full list of checks it performs.
So "the build succeeded" means only that a particular build process finished without detecting an error of its own in that environment. It does not confirm that a user can book the right time, that saving works, or that all the necessary scenarios have been checked. For that you need evidence of behaviour tied to the requirement.
Syntax, type, runtime and logic defects
These words describe different places where a problem becomes visible, and they can overlap:
- Syntax error: the parser cannot read the structure; for example, without a comma between
"port": 4100and"mode": "preview", the file is not valid JSON. - Type error: the operation does not suit the value. Calling a text method on
undefinedcan cause aTypeErrorat run time, so a type error may only become visible when the program runs. - Runtime error: the code is already running, but a problem occurs, such as a storage failure, a missing file or an exception.
- Logic defect: the code parses and runs but breaks a rule. For example,
<=instead of<can reject a permitted boundary time without any syntax error being reported.
A log message can give a hint, but it is not proof that the cause has been found. Line up the input value, the condition, the result and the rule by which the decision is made.
Asynchrony: the operation has started but not finished
An asynchronous operation is work whose result becomes known later, such as saving to storage or making a request to an external system. A promise in JavaScript is a value that represents the future completion, or failure, of such an operation. If a function starts saving and immediately returns a promise, the record has not necessarily been saved yet.
In the following hypothetical example, assume bookingStore.save returns a promise:
async function saveBooking(booking) {
const receipt = await bookingStore.save(booking);
return receipt;
}
async marks an asynchronous function; it returns a promise. await waits for the result of bookingStore.save within this function, and on success receipt receives the confirmation. If the save rejects the promise, the error propagates onwards unless the code handles it separately. This does not mean the whole program or the whole server stops in the meantime. MDN's official documentation explains promises and async/await as a way to work with the result and the failure of an asynchronous operation (Using promises, async function).
This is not a full explanation of concurrency, queues or cancelling operations; those are separate topics that come up elsewhere in the course. To read an agent's change, it is enough to notice the difference between calling a function and the value it promises to return later.
Example: changing a time limit and seeing the side effect
Situation. An invented ticket says: "Do not allow bookings less than 10 minutes before the start." For simplicity, a number stands for minutes from the start of the day; scheduled start times are kept in an array.
The original code, and the rule change:
function canBook(startMinute, currentMinute, busyStarts) {
if (startMinute < currentMinute) {
return false;
}
for (const busyStart of busyStarts) {
if (startMinute === busyStart) {
return false;
}
}
return true;
}
The original version rejects a time in the past and a time already taken. In it, startMinute and currentMinute are numbers, busyStarts is an array of numbers, and the result is true or false.
To meet the new requirement we need a boundary of exactly 10 minutes: a start 10 minutes away or later is allowed, provided that time is not taken.
function canBook(startMinute, currentMinute, busyStarts) {
if (startMinute < currentMinute + 10) {
return false;
}
for (const busyStart of busyStarts) {
if (startMinute === busyStart) {
return false;
}
}
return true;
}
The condition rejects every value strictly less than currentMinute + 10. With currentMinute = 600:
| Requested time | Difference | Array of busy times | Result under the rule |
|---|---|---|---|
| 609 | 9 minutes | [] |
false, too close |
| 610 | exactly 10 minutes | [] |
true, the boundary time is allowed |
| 620 | 20 minutes | [620] |
false, the slot is taken |
A faulty edit. If an agent changes < to <=, the value 610 will also be rejected, because 610 <= 610. The code stays syntactically correct and may pass the build, but it rejects a boundary time that the requirement allows. That is why it pays to read the condition as a rule in words and to check specific points: "9 minutes away", "exactly 10" and "later".
Result and limits. This example explains one boundary and an accidental mistake right next to it. In a real service, minutes have to be interpreted together with the date and the time zone; two meetings can overlap even when their start times differ. Someone else may also take the slot after the check. The system has to apply the important rules again at the moment of saving. The real contract depends on the business, the calendar and the storage; this teaching function is not a finished booking system.
How to read a change proposed by an agent
A function's contract is the inputs, result and errors it promises, which its callers have to take into account. When an agent changes a file, start by connecting the diff (a comparison of the state before and after) to the requirement:
- Which requirement and which function contract changed: its parameters, its result or its errors?
- Which files changed, and why; is the changed file a source, or is it generated from another file?
- Which tests cover the new behaviour, the important boundaries and the failure scenarios, and what remains unchecked?
- Does the requirement really need new files, settings and dependencies?
Reviewing a diff in full, and who is responsible for reviewing changes, is covered in AI Code Review.
A test that checks only the success line does not necessarily check a storage failure, a busy slot or a boundary value. On the other hand, being unfamiliar with a piece of syntax does not prove the code is wrong. If you do not know what a file is for, look for what reads or generates it, which commands the README mentions, and what the configuration shows. If there is no evidence yet, the correct conclusion is "needs investigating", not an immediate "bug".
Example: the agent changed the build output instead of the source
Situation. In an invented tree containing src/booking-form.js and dist/app.bundle.js, a ticket asks for the success confirmation text to be changed. The agent edits only dist/app.bundle.js, adds a time-formatting package to package.json and the lockfile, and sees the new text in its own local preview.
What the result actually confirms. Only that the generated file it looked at showed the new text in that local environment. It does not prove that the source file was changed, that the next build will keep the edit, that the new dependency is needed, or that the time in the confirmation is correct for the required time zone. If the team regenerates dist from src, the manual edit may vanish. If the dependency is not needed for the requirement, it enlarges the body of code that has to be installed and maintained, and changes the lockfile with no explained benefit.
Reviewing the changes. First check whether dist/app.bundle.js really is generated output in this repository: the name is a hint, but the proof is the build script, a comment in the file, or some other reference to the generator. If the source is src/booking-form.js, the edit belongs there, and the output should be rebuilt by the project's accepted process. Check whether the confirmation's contract has changed: for example, the text should appear only after the booking is saved, not after an attempt to save it. Check whether the package is needed for the implementation; if the requirement can be met without it, keeping the new dependency needs its own justification. For the behaviour, the appropriate checks are of a successful and a failed save, not just how the local page looks.
When the decision might be different. Some projects deliberately keep generated files in the repository for deployment or distribution. Do not delete dist, or reject a change to it, on the strength of its name alone. First find out how the project is built and what the release environment expects. GitHub describes the .gitattributes marker linguist-generated as a way to mark certain files as generated for diff display; it is a convenience hint on GitHub, not universal proof of where a file comes from (GitHub Docs: Customizing how changed files appear).
The lesson of the example. A local demo is narrow evidence about a single artefact. To assess the change, you need to establish which source produces the result, what behaviour is required, what the relevant tests cover, and why each dependency was added.
Summary
A repository is not just a set of folders: the code, data, configuration, checks and build output in it play different roles. Directory names and file extensions give hints, but the README, the imports, the configuration and the build scripts are the evidence of how this particular project is put together.
When reading JavaScript, look for the function's inputs, conditions, loops, outside values and result. Distinguish JSON, YAML and Markdown that hold data or explanations from code that makes decisions. The manifest describes the direct dependencies and the commands; the lockfile records the chosen dependency tree. Syntax parsing, static checking, building, running and behaviour testing answer different questions; success at one stage does not prove the product is correct.
When you analyse an agent's proposal, connect the diff to the requirement, the contract, the relevant tests, the source files and the need for any new dependencies. If there is no evidence yet, separate the unknown from a confirmed defect; success at a single stage does not, on its own, prove that the product works for the user.
Sources and further reading
All the web pages below were accessed on 23 September 2026. Living online documents may change after that date.
- MDN Contributors, Grammar and types — JavaScript Guide, current page; accessed 23 September 2026. Supports the explanation of values, types, variables, syntax and scope.
- MDN Contributors, Functions — JavaScript Guide and Control flow and error handling, current pages; accessed 23 September 2026. Support the definitions of function, parameter, result, conditions and loops.
- MDN Contributors, JavaScript modules, current page; accessed 23 September 2026. Supports the role of imports and the point that module loading depends on the environment.
- Node.js contributors, Modules: Packages, Node.js v26.10.0, Node.js v26.10.0 documentation; accessed 23 September 2026. Supports the explanation of a package's entry points and of how the Node.js manifest governs module loading.
- MDN Contributors, Using promises and async function, current pages; accessed 23 September 2026. Support the explanation of a future result,
async,awaitand errors. - Ecma International, ECMA-404: The JSON Data Interchange Syntax, 2nd edition, December 2017; accessed 23 September 2026. Supports the role of JSON as a data interchange syntax; the exact rules, including the absence of comments, are defined by the specification.
- YAML Language Development Team, YAML Ain't Markup Language, version 1.2.2, revision 1.2.2; accessed 23 September 2026. Supports the role of indentation and nesting in YAML.
- CommonMark contributors, CommonMark Spec 0.31.2, version 0.31.2; accessed 23 September 2026. Supports the short description of Markdown and the caveat about differences between extensions.
- MDN Contributors, Creating the content, current tutorial page; accessed 23 September 2026. Supports the definition of HTML and its role in page structure.
- MDN Contributors, What is CSS?, current tutorial page; accessed 23 September 2026. Supports the definition of CSS and its role in styling HTML.
- MDN, About MDN, the project's official history page; accessed 23 September 2026. Confirms that MDN stood for Mozilla Developer Network in the 2010 name; the documentation is now called MDN Web Docs.
- Node.js contributors, Environment Variables, Node.js v26.10.0, Node.js v26.10.0 documentation; accessed 23 September 2026. Supports the description of environment variables and the limits of a shared
.envformat. - npm, Specifying dependencies and devDependencies and package-lock.json, current npm documentation; accessed 23 September 2026. Support the roles of the dependency groups and the purpose of a lockfile; details depend on the npm version.
- Microsoft, TypeScript for the New Programmer, current TypeScript Handbook; accessed 23 September 2026. Supports static checking and how it differs from run-time behaviour.
- GitHub Docs, About the repository README file, Ignoring files and Customizing how changed files appear, current pages; accessed 23 September 2026. Support the description of the README, ignoring not-yet-tracked files, and GitHub's markers for generated material.
- Sindre Sorhus, p-limit v7.3.3 README, package.json and test.js, tag v7.3.3; accessed 23 September 2026. Used as a small open-source example of a README, a manifest and tests; the specific structure is not presented as a general standard. None of this project's code or tests was run.