On this page
Of the 53 repos with 10,000+ stars that have a function-length record in our index, the longest function is RunPanoramaStitchSelfTest in Microsoft PowerToys. It is 6,967 lines long, it lives in a single 18,048-line C++ file, and it is a test suite written as one function.
We record the longest function in every repo we index. I took the list for popular repos, opened each function in the source at the exact commit we indexed, and measured it again by hand. Then I read them to find out why they got that long.
The list
The ten longest functions in repos with 10,000+ GitHub stars, longest first, then three more further down the list that explain something. Lengths are at the commit we indexed (linked), and the last column says what that function looks like on the default branch today.
| Repo | Function | Lines | What it is | Today |
|---|---|---|---|---|
| microsoft/PowerToys | RunPanoramaStitchSelfTest | 6,967 | a self-test suite | 6,967 |
| NousResearch/hermes-agent | run_conversation | 6,591 | the agent loop | 48, split up |
| vectorize-io/hindsight | _register_routes | 5,209 | 99 HTTP routes | 5,260 |
| openclaw/openclaw | runEmbeddedAttempt | 4,972 | one agent run | 35, split up |
| pewdiepie-archdaemon/odysseus | setup_email_routes | 4,640 | 57 email routes | |
| andrewyng/openworker | make_integration_tools | 4,505 | 133 tool functions | |
| tt-a1i/archify | compileWorkflowInternal | 3,565 | a compiler pass | |
| debpalash/voicestudio | DubPage | 2,775 | a single TSX page component | |
| colbymchenry/codegraph | main | 2,348 | 22 CLI commands | |
| emdash-cms/emdash | createMcpServer | 2,223 | 55 MCP tools | |
| Further down | ||||
| apache/airflow | get_provider_info | 1,703 | generated | |
| go-gitea/gitea | registerWebRoutes | 1,464 | the web route table | 1,470 |
| fastapi/fastapi | FastAPI.__init__ | 988 | 39 documented parameters | 988 |
Scroll the table sideways to see every column.
A blank "Today" cell means I didn't re-measure it on the current branch.
Reading down the "What it is" column, the functions sort into registries, generated code, a test that grew, and core loops. Only the core loop is the kind of long function people usually warn about.
1. The registry
Half the list is the same shape: one function that defines everything a server or CLI exposes.
Hindsight's _register_routes declares 99 HTTP routes inside one function. Odysseus' setup_email_routes declares 57. emdash's createMcpServer registers 55 MCP tools. codegraph's main sets up 22 CLI commands. openworker's make_integration_tools defines 133 inner functions, one per tool. Gitea's registerWebRoutes is close to 800 route calls in a row.
Each handler needs the same shared objects (the app, the database client, the config), and the easiest way to give them all access is to define every handler inside one function that receives those objects, so each handler is a closure over them. The language calls that a function, so every tool that measures "function length" counts it as one, even though it reads like a module with one long table of contents.
A registry is less of a problem than its length suggests, because every entry looks the same and the function is easy to scan. It starts to hurt at merge time: when several people add routes in the same week, they all edit the same 5,000-line function, and the conflicts land in one place. Splitting the routes by area (one register function per resource) fixes that without changing how anything works.
2. Generated code
Airflow's get_provider_info is 1,703 lines, and the file opens with "NOTE! THIS FILE IS AUTOMATICALLY GENERATED AND WILL BE OVERWRITTEN!" It returns one big dictionary describing the Google provider, and the header says it is overwritten on every generation, so nobody edits it by hand.
Suricata, the network security monitor, has a 3,500-line C function in a file marked "DO NOT EDIT. THIS FILE IS AUTO-GENERATED." (Suricata has 6,655 stars, so it isn't in the table above, but it makes the same point.)
Generated code should be measured and then ignored. If a tool flags it, the fix belongs in the tool's config.
3. The test that grew
PowerToys' RunPanoramaStitchSelfTest is the longest function on the list and it is a test. It belongs to ZoomIt's panorama capture, which stitches screenshots into one long image as you scroll. The function runs scenario after scenario: small scroll steps, near-duplicate frames, dark code editors whose repeating line pattern can fool the matcher into locking onto 2× or 4× the real scroll distance. Several scenarios are labelled as regression tests for specific bugs, with the debug log name that reproduced them.
That is a reasonable way for a test to grow. Every bug adds one more scenario, each scenario is self-contained, and keeping them in one function means they share setup and run in a fixed order with one exit code. It still runs to 6,967 lines, and most test frameworks would let you register each scenario as its own test and get per-scenario failures for free. It is the same function on the main branch today.
4. The core loop
This is the kind people mean when they warn you about long functions, and it is where the most interesting things happened.
Hermes Agent's run_conversation was 6,591 lines at our index of 19 August: the whole agent loop for one user turn, with retries, compression, streaming, tool calls and cancellation, in one function with 521 if/elif lines. About 28% of its lines were comments, many of them long explanations of a past bug and why the code handles it the way it does. openclaw's runEmbeddedAttempt was 4,972 lines at our index of 26 June, with 90 awaits in one body.
Both have since been split. On today's default branches, run_conversation is 48 lines and runEmbeddedAttempt is 35, with the work moved into smaller functions around them. Both repos are among the fastest-moving on GitHub, with hundreds of commits a day. I'd guess the pace is why: a single function that every change has to touch becomes a bottleneck for the whole team.
FastAPI's init, mostly documentation
FastAPI's __init__ is 988 lines, and about 830 of them are the parameter list. It takes 39 parameters, and each one carries its own documentation inline, through Annotated[..., Doc("...")], so editors can show the docs on hover. The body that does the work is around 160 lines, so counting it as a long function mostly counts documentation.
Applying this to your own code
Before you treat a long function as a problem, ask which of the four it is:
- A registry is fine to read and painful to merge, so split it by area when merges start to hurt.
- Generated code should be excluded from your metrics.
- A test that grew can become one test per scenario, mostly for better failure reports.
- A core loop is the one to split, before every feature has to go through it.
repowise records the longest function for every repo it indexes, along with the file it lives in, and links the health findings for that file. If you want to see yours, paste any GitHub URL and open the stats page. Here is PowerToys.
How we measured
For every public repo with 500+ stars that has a stats record in our index (106 repos, with FastAPI counted once although we list it under two owners), we took the longest function the parser found. I kept repos with 10,000+ stars, downloaded each file from GitHub at the exact commit we indexed, and measured the function again: Python with the standard ast module, C, C++, Go, JavaScript and TypeScript by matching braces from the definition. Every number in the table matched our index. Length here is lines from the definition to the closing line, including comments and blank lines. "Today" means the default branch on 6 October 2026. Counts of routes, tools, if lines and comments are simple line matches, so treat them as approximate.