GSoC 2026 Final Report: Automated Webpack Documentation Pipeline ๐ซ
Name: Mohamed Shams El-Deen (@moshams272) - Organization: Webpack - Mentors: Aviv Keller (@avivkeller), Claudio Wunder (@ovflowd), Sebastian Beltran (@bjohansebas) - GSoC Teammates: Nikhil Kumar Rajak (@ryzrr), Tushar Thakur (@TusharThakur04) Introduction As part of Google Summer of Code 2026, I worked on redesigning Webpack's documentation. Historically in webpack.js.org, every time an API changed in Webpack, a team member had to manually update the documentation. Our goal was to eliminate this manual overhead. To make this, we took advantage of the TypeScript compiler that gives us APIs in types.d.ts file, the typedoc-plugin-markdown that converts TypeScript APIs to markdown, and the nodejs/doc-kit that adds links and customized UI. However, node.js/doc-kit needs a markdown that follows specific rules. So, we cann't use the TypeDoc output directly. We need to build a tool to customize it correctly to solve this, and that's our project webpack-doc-kit. This post documents the exact implementations that brought this automated documentation to life. 1. Main Contributions ๐ฅ 1.1. Cross-Ecosystem Features (webpack/webpack-doc-kit & nodejs/doc-kit) The Advanced TypeScript AST Parsing Pipeline: doc-kit PRs: PR #763, PR #668, PR #883, PR #814 webpack-doc-kit PRs: PR #169, PR #164, PR #113 Generating flawless markdown required a parser that understood highly complex TypeScript signatures. Both upstream (doc-kit ) and downstream (webpack-doc-kit ) were dropping keywords, misinterpreting generics, and failing on deep intersections. Implementation: - In doc-kit , I implemented a Top-Down Recursive Descent Parser to safely traverse nested generics and operator precedence (=> ,| ,& ). I enhanced the type parser to fully support TS prefix operators and complex regex linking. - In webpack-doc-kit , I aligned the AST to the new upstream parser. I isolated intersection AST nodes, enhanced direct AST support for query and type operator prefixes nodes, and injected spaces inside generics to bypass HTML parsers safely beforedoc-kit processes them. Note: After that, we implemented a much stronger parser (oxc-parser), so my early workarounds were removed because the new parser handled everything automatically. However, my solutions were first steps that kept the project moving forward. Standardizing YAML Frontmatter & Meta Data Injection: webpack-doc-kit PRs: PR #136 The old tool used HTML comments to save data ( ). But modern tools use Standard --- YAML blocks. We also needed to add a source tag automatically so the "Edit this page" button would work on the website. Implementation: - In doc-kit , I implemented a pre-AST step. The engine now detects standard--- frontmatter blocks at the top of a file, converts them into the HTML comments in memory, and passes them to the AST parser. This added support for modern YAML without breaking old code. - In webpack-doc-kit , I wrote theMarkdownPageEvent.END hook fromtypedoc-markdown-plugin to capture the final Markdown string in memory, manually calculated the GitHub link source and injected it in the frontmatter block directly into the output. Automating Static Assets Migration: doc-kit PRs: PR #753 webpack-doc-kit PRs: PR #156 Local images inside markdown files were not copied to the final out/ folder. This caused broken images on the live site. Implementation: - In doc-kit , I added a new configuration feature that allows developers to explicitly define custom paths for files they want to copy, thendoc-kit copies them to an/assets/ folder during the build. - In webpack-doc-kit , I used this new feature to specify the exact paths for Webpack's images. Aligning Markdown Output with Node.js doc-kit Specifications: webpack-doc-kit PRs: PR #133, PR #126, PR #118 The generated markdown for Webpack did not perfectly match the strict rules of the @node-core/doc-kit tool. Implementation: - I fixed multiple issues to match the rules. For example, I stopped classes from showing that they inherit from themselves, fixed multi-line tags (like @deprecated ) so they wrap correctly in blockquotes, also enabled nested optional and rest parameter syntax. Changing Overloads Representation: doc-kit PRs: PR #1047 webpack-doc-kit PRs: PR #187 Every overload simply repeated the "Call Signature" heading followed by its specific details (parameters, return types) without the real signature representation. Implementation: - In doc-kit , All overload signatures are parsed from the MDX AST, combined, and presented together in a single syntax-highlighted code block at the top. The specific details for each overload (parameters, return types) are then rendered inside an Overload Tabs component. - In webpack-doc-kit , I replaced the headings in the legacy theme by the real, specific signature of each overload directly in the heading, while removing duplicate parent headings. 1.2. webpack/webpack-doc-kit Core Implementations The Destructured Parameters AST: PRs: PR #167 When a function takes destructured parameters (like function config({ name, age }) ), TypeScript hides the real names and replaces them with a strange word: __namedParameters . Implementation: - I wrote a Converter.EVENT_RESOLVE_BEGIN hook fromtypedoc-markdown-plugin that catches__namedParameters in the code tree. - Then extracts the real parameter names ( name ,age ) and puts them in a flat, readable list. Replacing Custom Lint Scripts with a Native ESLint Markdown Rule: PRs: PR #189 Sometimes the title inside the YAML block didn't match the H1 heading of the page. Implementation: - First, I implemented a script to do this, but it brakes easily and did not work inside code editors. - Then I created a native ESLint rule using @eslint/markdown that reads the Markdown files. It instantly warns the developer in VS Code if the titles do not match. It also has an "auto-fix" feature that corrects the titles automatically. The Blog Architecture & Data Pipeline: Webpack needed a blog system to share updates with the community. Implementation: - I built a Data Pipeline that reads all markdown posts, extracts their metadata (e.g., author, date, categories), and saves them into a centralized JSON database. - I designed a full UI Architecture from scratch, creating React components for the blog layout, post cards, category filters, cover images, and github authors' images components. Integrating the Early Garbage Collector for Missing Exports: PRs: PR #109 Many important Webpack types were missing from the documentation because they were not exported correctly. I used a typedoc-plugin-missing-exports plugin to fix this, but it extracted +600 internal types, adding too much noise and wasting memory. Implementation: - I created an Early Garbage Collector Converter.EVENT_RESOLVE_END hook that runs after the code is parsed. It safely deletes +300 useless noise types to save memory. It keeps the ~300 important Webpack types. Centralizing the Source of Truth for URLs: PRs: PR #178, PR #142, PR #128 Different parts of the code were generating URLs in different ways. This caused many issues, like broken links and 404 errors. Implementation: - I moved all the URL logic into one central file. I wrote clean functions to handle all links across the project. Automated Testing for Custom Theme: PRs: PR #230, PR #232, PR #235, PR #238, PR #240 The new custom design theme didn't have any automated tests. This made it very risky to change the code because things could easily break. Implementation: - I built a full theme testing system and inject it in the CI/CD. It tests all the theme components and takes snapshots of the generated markdown to make sure everything looks correct. Extracting Webpack Hooks Group: PRs: PR #212 Webpack hooks (which are very important for plugin developers) were mixed with other general APIs, making them hard to find. Implementation: - I extracted all the Hooks into a new distinct section in the sidebar menu. This makes it much easier for developers to find what they need. 2. Additional Contributions ๐ 2.1. webpack/webpack-doc-kit Core Implementations - PR #179: Fixed Vercel deployment crash by referencing the cached Github repo instead of local existsSync paths. - PR #252, PR #253: Authenticated GitHub API requests and normalized npm v12+ npm pack JSON logic. - PR #248, PR #245: Migrated live interactive components and built the StackBlitzPreview block. - PR #205: Implemented an automated sitemap generation script for better SEO. - PR #204: Dynamically appended "Added Version" metadata to Webpack configuration APIs. - PR #184, PR #183: Stripped empty "Type Parameters" headings to clean up callable interface rendering. - PR #165: Added an Optimization taxonomy group to the sidebar layout. - PR #162, PR #161: Replaced placeholder /docs andguides STUB markers with full production-ready Webpack overviews. - PR #134: Auto-mapped Type Aliases dynamically during AST linking. 2.2. Upstream nodejs/doc-kit Core Implementations - PR #848: Added missing standard types (like void ) so their links work correctly. - PR #762: Fixed a sidebar bug so it only highlights exact link matches. - PR #760: Cleaned up the code by fixing wrong comments and removing unused variables. Conclusion ๐ Through this GSoC program, my teammates and I successfully designed and implemented a fully automated documentation pipeline for Webpack. The project involved deep architectural decisions from building custom AST parsers to building custom UI components and establishing CI/CD workflows across both webpack/webpack-doc-kit and upstream nodejs/doc-kit . Together, we completely eliminated the need for manual API documentation update by bridging the gap between Webpack's source code and its developer community. Acknowledgments ๐ค A massive thanks to my mentors Aviv Keller (@avivkeller), Claudio Wunder (@ovflowd), and Sebastian Beltran (@bjohansebas) for their helping, patience, and architectural guidance. I also want to thank my GSoC teammates Nikhil Kumar Rajak (@ryzrr) and Tushar Thakur (@T
Comments
No comments yet. Start the discussion.