GitHub
Code Analysis
Repository
Programming
Software Development

Can you get the number of lines of code from a GitHub repository?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

GitHub does not display the total lines of code (LOC) for a repository directly. To get this number, use cloc (Count Lines of Code) after cloning the repo, the GitHub API's statistics endpoint, or a quick git ls-files | xargs wc -l command. Each method has different tradeoffs in accuracy, setup, and what it counts.

Method 1: Using cloc (Most Accurate)

cloc is the gold standard for counting lines of code. It differentiates between code, comments, and blank lines, and it recognizes over 250 programming languages.

Install cloc

bash
1# macOS
2brew install cloc
3
4# Ubuntu/Debian
5sudo apt install cloc
6
7# Windows (with Chocolatey)
8choco install cloc
9
10# Or via npm
11npm install -g cloc

Clone and Count

bash
git clone https://github.com/facebook/react.git
cd react
cloc .

Example output:

 
1-------------------------------------------------------------------------------
2Language                     files          blank        comment           code
3-------------------------------------------------------------------------------
4JavaScript                    1245           8432          12567          98234
5TypeScript                     234           1234           2345          23456
6JSON                            89              0              0           5678
7Markdown                        67           1234              0           4567
8CSS                             23            456            234           2345
9-------------------------------------------------------------------------------
10SUM:                          1658          11356          15146         134280
11-------------------------------------------------------------------------------

Useful cloc Options

bash
1# Exclude specific directories
2cloc . --exclude-dir=node_modules,dist,build,vendor
3
4# Count only specific languages
5cloc . --include-lang=Python,JavaScript
6
7# Output as JSON (for scripting)
8cloc . --json --out=loc-report.json
9
10# Compare two git commits
11cloc --diff HEAD~10 HEAD
12
13# Count a specific branch without cloning
14cloc --git https://github.com/user/repo.git

Method 2: Using the GitHub API

The GitHub API provides language byte counts, which you can use to estimate lines of code without cloning.

Get Language Statistics

bash
1# Using curl
2curl -s https://api.github.com/repos/facebook/react/languages
3
4# Using gh CLI (if authenticated)
5gh api repos/facebook/react/languages

Output:

json
1{
2  "JavaScript": 5765432,
3  "TypeScript": 1234567,
4  "HTML": 234567,
5  "CSS": 123456
6}

These numbers are bytes, not lines. To estimate lines, divide by an average of 35-45 bytes per line (varies by language):

python
1import requests
2import json
3
4response = requests.get("https://api.github.com/repos/facebook/react/languages")
5languages = response.json()
6
7total_bytes = sum(languages.values())
8estimated_lines = total_bytes // 40  # rough estimate
9
10print(f"Total bytes: {total_bytes:,}")
11print(f"Estimated lines: {estimated_lines:,}")
12
13for lang, bytes_count in sorted(languages.items(), key=lambda x: -x[1]):
14    print(f"  {lang}: ~{bytes_count // 40:,} lines ({bytes_count:,} bytes)")

Get Contributor Statistics (Includes Additions/Deletions)

bash
# Get weekly commit activity
gh api repos/facebook/react/stats/code_frequency

This returns weekly additions and deletions. Summing all additions minus deletions gives the current net LOC, though this includes all file types.

Method 3: Quick git Command (No Extra Tools)

If you already have the repository cloned, use this one-liner:

bash
git ls-files | xargs wc -l

This counts every line in every tracked file, including comments, blank lines, configuration files, and generated code. It is fast but not precise.

Improved Version: Filter by File Type

bash
1# Count only Python files
2git ls-files '*.py' | xargs wc -l
3
4# Count only JavaScript and TypeScript
5git ls-files '*.js' '*.ts' '*.jsx' '*.tsx' | xargs wc -l
6
7# Exclude test files
8git ls-files | grep -v -E '(test|spec|__test__)' | xargs wc -l

Handle Filenames with Spaces

bash
git ls-files -z | xargs -0 wc -l

The -z flag uses null bytes as delimiters instead of newlines, preventing errors with filenames that contain spaces.

Method 4: GitHub Linguist (What GitHub Uses)

GitHub uses Linguist internally to compute the language bar you see on repository pages. You can run it locally:

bash
1# Install (requires Ruby)
2gem install github-linguist
3
4# Clone and analyze
5git clone https://github.com/user/repo.git
6cd repo
7github-linguist --breakdown

Linguist respects .gitattributes rules, so vendor files and generated code are excluded by default (matching what GitHub shows).

Method 5: tokei (Fast Alternative to cloc)

tokei is a Rust-based LOC counter that is significantly faster than cloc on large repositories:

bash
1# Install
2brew install tokei          # macOS
3cargo install tokei         # via Rust
4sudo apt install tokei      # Ubuntu 22.04+
5
6# Count
7tokei /path/to/repo
8
9# Exclude directories
10tokei /path/to/repo --exclude node_modules dist
11
12# Output as JSON
13tokei /path/to/repo -o json

Example output:

 
1===============================================================================
2 Language            Files        Lines         Code     Comments       Blanks
3===============================================================================
4 JavaScript           1245        119233        98234        12567         8432
5 TypeScript            234         27035        23456         2345         1234
6 JSON                   89          5678         5678            0            0
7===============================================================================
8 Total                1568        151946       127368        14912         9666
9===============================================================================

Method 6: Without Cloning (Remote Analysis)

If you do not want to clone the repository:

Using the GitHub Stats Page

Navigate to https://github.com/{owner}/{repo}/graphs/contributors. This page shows additions and deletions per contributor. The "Additions" column roughly indicates total lines ever written (not current LOC).

Using codetabs API

bash
curl "https://api.codetabs.com/v1/loc?github=facebook/react"

This free API returns LOC without requiring you to clone. Rate limits apply.

Using scc via Docker

bash
# Analyze a GitHub repo without cloning
docker run --rm -v /tmp:/tmp boyter/scc \
  bash -c "git clone --depth 1 https://github.com/user/repo.git /tmp/repo && scc /tmp/repo"

Comparison of Methods

MethodAccuracySpeedNeeds Clone?Differentiates Code/Comments?Setup
clocHighMediumYesYesInstall package
tokeiHighFastYesYesInstall package
sccHighFastYesYesInstall package
git ls-files + wcLowFastYesNoNone
GitHub APIEstimateFastNoNoAPI token
GitHub LinguistHighSlowYesNo (counts all lines)Ruby + gem
codetabs APIMediumFastNoYesNone

Counting Lines for a Specific Commit or Branch

bash
1# Count LOC at a specific commit
2git checkout abc1234
3cloc .
4
5# Count LOC on a specific branch
6git checkout feature-branch
7cloc .
8
9# Compare LOC between two branches (shows diff)
10cloc --diff main feature-branch

Automating LOC Tracking in CI

You can track LOC trends over time by adding a CI step:

yaml
1# GitHub Actions example
2- name: Count lines of code
3  run: |
4    sudo apt-get install -y cloc
5    cloc . --json --out=loc-report.json --exclude-dir=node_modules,dist
6    echo "Total lines: $(cat loc-report.json | jq '.SUM.code')"

Common Pitfalls

  • Counting node_modules or vendor directories: These contain third-party code and inflate your LOC by orders of magnitude. Always exclude dependency directories: cloc . --exclude-dir=node_modules,vendor,dist.
  • Confusing bytes with lines: The GitHub API returns bytes per language, not lines. A rough conversion is 35-45 bytes per line, but this varies significantly. Do not report API byte counts as line counts.
  • Counting generated code: Build artifacts, compiled outputs, and auto-generated files (like package-lock.json) can add hundreds of thousands of lines. Use .gitattributes or cloc's --exclude-ext to skip them.
  • LOC as a productivity metric: Lines of code is a measure of codebase size, not developer productivity or code quality. A refactoring that reduces LOC by 30% can be more valuable than one that adds 10,000 lines.
  • Shallow clones missing history: git clone --depth 1 works fine for current LOC counting, but cloc --diff and history-based analysis require full history. Use a full clone for those operations.
  • Rate limiting on the GitHub API: Unauthenticated requests are limited to 60 per hour. Authenticate with a personal access token for 5,000 requests per hour.

Summary

  • GitHub does not show total LOC directly. Use cloc, tokei, or scc for accurate counts after cloning.
  • cloc . --exclude-dir=node_modules,dist is the most commonly used command for an accurate count.
  • For a quick estimate without extra tools, use git ls-files '*.py' '*.js' | xargs wc -l.
  • The GitHub API at /repos/{owner}/{repo}/languages returns byte counts per language, not line counts. Divide by roughly 40 for a line estimate.
  • Always exclude vendor/dependency directories and generated files from your count.
  • tokei and scc are faster alternatives to cloc for very large repositories.

Course illustration
Course illustration

All Rights Reserved.