How the free-programming-books Repository Is Structured and Organized

The free-programming-books repository follows a flat, language-centric Jekyll site structure that organizes thousands of learning resources into modular Markdown directories like books/, courses/, and casts/, enabling easy contribution and static site generation.

The EbookFoundation/free-programming-books repository is a pure-content static site that aggregates freely available programming learning materials. Its architecture prioritizes readability and maintainability through a strict file-based hierarchy, allowing contributors to edit simple Markdown files while Jekyll handles the site rendering.

Top-Level Repository Structure

The repository root contains configuration files, documentation, and entry points that define the project's behavior and community standards.

Entry Point and Configuration

The README.md serves as the primary landing page, containing project badges, a quick introduction, and a condensed table of contents. The _config.yml file configures the Jekyll static site generator, specifying the theme, enabled plugins like jekyll-relative-links for internal link resolution, and build settings that allow the site to function both on GitHub Pages and in raw repository view.

Standard governance files reside at the root level: LICENSE defines the legal terms, CODE_OF_CONDUCT.md establishes community standards, and CONTRIBUTING.md provides the contribution workflow. The docs/ directory contains extended documentation including translation guides and detailed HOW-TO instructions.

Content Organization by Media Type

Learning materials are segregated into four primary directories based on format, each following consistent internal formatting patterns.

The books/ Directory

The books/ directory stores the core data files listing free programming books. Resources are organized using two parallel classification schemes:

Each file follows a rigid format: a level-2 heading for the category, followed by bullet lists where each entry contains the resource title, URL, and optional description.

Courses, Casts, and Supplementary Materials

Three additional directories mirror the books/ structure:

Classification System: Language vs. Subject

The repository implements a dual taxonomy to prevent resource duplication while maintaining discoverability. Language-specific resources reside in their respective *-langs.md files, keeping the lists focused and navigable. Subject-centric resources that transcend specific programming languages are isolated in books/free-programming-books-subjects.md, ensuring Python books do not clutter general computer science theory lists.

Automation and Quality Control

Despite being a content repository, the project employs automated tooling to maintain formatting consistency across thousands of entries.

Linting and Validation Scripts

The scripts/ directory contains helper utilities used by the CI pipeline. The scripts/rtl_ltr_linter.py script validates new entries for proper Right-to-Left (RTL) and Left-to-Right (LTR) text direction consistency, ensuring that mixed-language content displays correctly across different locales.

GitHub Integration

The .github/ directory houses GitHub-specific configurations including the Dependabot setup in .github/dependabot.yml for dependency updates and pull request templates. GitHub Actions workflows automatically trigger the linter on pull requests, validating formatting before maintainers review submissions.

Static Site Generation

The repository functions as a Jekyll site, converting the Markdown data files into a searchable, navigable website.

Jekyll Configuration

The _config.yml declares the jekyll-relative-links plugin, which rewrites internal file references so that links resolve correctly whether viewed on GitHub.com or the rendered GitHub Pages site. This ensures that cross-references between the English book list and the courses list remain functional in both contexts.

Asset Management

Visual assets for the generated site include favicon.ico at the root and HTML includes in _includes/ (such as _includes/head-custom.html) that inject custom metadata or tracking scripts into the site header.

Programmatic Access Patterns

Developers interact with the repository structure through several common patterns:

Linking to specific sections from external Markdown:

[Python free books](https://github.com/EbookFoundation/free-programming-books/blob/main/books/free-programming-books-en.md#python)

Fetching raw content via command line for local processing:

curl -s https://raw.githubusercontent.com/EbookFoundation/free-programming-books/main/books/free-programming-books-en.md | grep -i "flask"

Accessing the search index programmatically:

fetch('https://ebookfoundation.github.io/free-programming-books-search/assets/search-index.json')
  .then(r => r.json())
  .then(index => {
    const results = index.filter(item => /flask/i.test(item.title));
    console.log(results);
  });

Summary

  • The repository uses a flat content model with no database or dynamic backend—only Markdown files processed by Jekyll
  • Resources are organized by media type (books/, courses/, casts/, more/) and by language within each directory
  • The rtl_ltr_linter.py script enforces formatting standards and text direction consistency
  • Dual classification separates language-specific tutorials from subject-agnostic theoretical content
  • Jekyll-relative-links plugin ensures URLs work in both raw GitHub view and the rendered site

Frequently Asked Questions

What is the difference between the books/ and courses/ directories?

The books/ directory contains textual resources like PDFs, ePubs, and online book-length documentation, while the courses/ directory specifically indexes video-based tutorials, MOOCs, and structured online classes. Both follow identical Markdown formatting patterns but are separated to help users distinguish between reading material and video instruction.

How does the repository handle resources in multiple languages?

Each language receives its own dedicated file within the relevant media directory (e.g., books/free-programming-books-en.md for English, books/free-programming-books-es.md for Spanish). This file-per-language approach allows localized communities to maintain their own lists without merge conflicts, while the rtl_ltr_linter.py script ensures that Right-to-Left languages like Arabic or Hebrew display correctly alongside Left-to-Right content.

Is there a database or API backend for the free-programming-books repository?

No, the repository maintains a read-only data store architecture with zero runtime dependencies. The "API" consists of raw GitHub URLs to Markdown files, and the search functionality is powered by a static JSON index generated at build time by Jekyll. This design ensures the resource list remains accessible even offline or in environments with restricted connectivity.

What is the purpose of the scripts/rtl_ltr_linter.py file?

The scripts/rtl_ltr_linter.py script is a CI utility that checks pull requests for proper Unicode directionality markers. It validates that Right-to-Left (RTL) script content (such as Arabic or Hebrew titles) includes appropriate directional formatting characters, preventing display corruption when the Jekyll site renders the content or when users view the raw Markdown on GitHub.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →