Use the form above. Parameters, code examples and FAQ are grouped in the documentation section below.
Free GitHub LOC counter: count lines of code (LOC) of any GitHub or GitLab repository by programming language — files, blanks, comments and code share. No signup, no install, with a free LOC API.
&branch=name.
*.min.js and binary files are skipped.
/v1/loc API and filter the JSON.
/v1/loc?github=user/repo returns JSON per language, with an optional branch parameter.
curl /v1/loc?github=username/reponame GET /v1/loc?github=username/reponame
GET /v1/loc?gitlab=username/reponame
/v1/loc?SOURCE=USERNAME/REPONAME&branch=branchName/v1/loc?SOURCE=USERNAME/REPONAME&ignored=DIRNAME1,DIRNAME2,FILENAME
/v1/loc?github=cli/cli
/v1/loc?gitlab=gitlab-org/gitlab-runner
/v1/loc?github=ImageMagick/ImageMagick&branch=main
/v1/loc?github=cli/cli&ignored=docs,website
detail=1 to also get every file and a per-extension breakdown./v1/loc?github=username/reponame&detail=1
[{
"language": "JavaScript",
"files": 1,
"lines": 176,
"blanks": 14,
"comments": 6,
"linesOfCode": 156
},
... more languages
{
"language": "Total",
"files": 8,
"lines": 921,
"blanks": 148,
"comments": 46,
"linesOfCode": 743
}]
Count lines of code in any public GitHub or GitLab repository, broken down by language, plus per-file and per-extension detail.
| Endpoint | Returns | Example |
|---|---|---|
/v1/loc | JSON | github=torvalds/linux |
| Name | Type | Default | Description |
|---|---|---|---|
github | string | required | Repository as user/repo. Use gitlab for GitLab instead. |
gitlab | string | required | Repository as group[/subgroup]/repo. Use github for GitHub instead. |
branch | string | auto | Branch to count. Defaults to the repository default branch. |
ignored | string | - | Comma-separated files or directories to exclude, e.g. vendor,dist,*.snap. |
detail | string | - | Set to 1 to also return extensions[] and files[]. |
curl 'https://freetools.one/v1/loc?github=torvalds/linux'const stats = await (await fetch('https://freetools.one/v1/loc?github=cli/cli')).json();
const total = stats.find(l => l.language === 'Total');
console.log(total.linesOfCode, 'LOC in', total.files, 'files');import requests
stats = requests.get('https://freetools.one/v1/loc',
params={'github': 'cli/cli'}).json()
total = [s for s in stats if s['language'] == 'Total'][0]
print(total['linesOfCode'], 'LOC in', total['files'], 'files')[
{
"language": "Rust",
"files": 300,
"lines": 40000,
"blanks": 3000,
"comments": 2000,
"linesOfCode": 35000,
"percent": 91.9
},
{
"language": "Total",
"files": 512,
"lines": 43500,
"blanks": 3200,
"comments": 2300,
"linesOfCode": 38000,
"percent": 100.0
}
]
Call /v1/loc?github=user/repo. The response breaks the repository down by language and reports files, lines, blanks, comments and lines of code for each one.
The tool counts whole repositories because it works from the source archive. For one file, request detail=1 and filter the files[] array by path, or use ignored= to exclude everything else.
vendor, dist, build, target, out, node_modules, .next, coverage, venv and .venv directories, generated bundles such as *.min.js, and any file containing binary data.
Up to 300 MB compressed and 1.5 GB uncompressed, with a ceiling of 200,000 files. Larger archives are rejected with HTTP 413 rather than timing out.